Warning, file /webapps/ocs-webserver/library/Zend/Service/WindowsAzure/Management/Client.php was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Service_WindowsAzure
0017  * @subpackage Management
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_Service_WindowsAzure_Management_OperationStatusInstance
0025  */
0026 // require_once 'Zend/Service/WindowsAzure/Management/OperationStatusInstance.php';
0027 
0028 /**
0029  * @see Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance
0030  */
0031 // require_once 'Zend/Service/WindowsAzure/Management/SubscriptionOperationInstance.php';
0032 
0033 /**
0034  * @see Zend_Service_WindowsAzure_Management_DeploymentInstance
0035  */
0036 // require_once 'Zend/Service/WindowsAzure/Management/DeploymentInstance.php';
0037 
0038 /**
0039  * @see Zend_Service_WindowsAzure_Storage_Blob
0040  */
0041 // require_once 'Zend/Service/WindowsAzure/Storage/Blob.php';
0042 
0043 /**
0044  * @see Zend_Service_WindowsAzure_Storage_Table
0045  */
0046 // require_once 'Zend/Service/WindowsAzure/Storage/Table.php';
0047 
0048 /**
0049  * @see Zend_Service_WindowsAzure_Management_HostedServiceInstance
0050  */
0051 // require_once 'Zend/Service/WindowsAzure/Management/HostedServiceInstance.php';
0052 
0053 /**
0054  * @see Zend_Service_WindowsAzure_Management_CertificateInstance
0055  */
0056 // require_once 'Zend/Service/WindowsAzure/Management/CertificateInstance.php';
0057 
0058 /**
0059  * @see Zend_Service_WindowsAzure_Management_AffinityGroupInstance
0060  */
0061 // require_once 'Zend/Service/WindowsAzure/Management/AffinityGroupInstance.php';
0062 
0063 /**
0064  * @see Zend_Service_WindowsAzure_Management_LocationInstance
0065  */
0066 // require_once 'Zend/Service/WindowsAzure/Management/LocationInstance.php';
0067 
0068 /**
0069  * @see Zend_Service_WindowsAzure_Management_OperatingSystemInstance
0070  */
0071 // require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php';
0072 
0073 /**
0074  * @see Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance
0075  */
0076 // require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemFamilyInstance.php';
0077 
0078 /** @see Zend_Xml_Security */
0079 // require_once 'Zend/Xml/Security.php';
0080 
0081 /**
0082  * @category   Zend
0083  * @package    Zend_Service_WindowsAzure
0084  * @subpackage Management
0085  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0086  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0087  */
0088 class Zend_Service_WindowsAzure_Management_Client
0089 {
0090   /**
0091    * Management service URL
0092    */
0093   const URL_MANAGEMENT        = "https://management.core.windows.net";
0094   
0095   /**
0096    * Operations
0097    */
0098   const OP_OPERATIONS                = "operations";
0099   const OP_STORAGE_ACCOUNTS          = "services/storageservices";
0100   const OP_HOSTED_SERVICES           = "services/hostedservices";
0101   const OP_AFFINITYGROUPS            = "affinitygroups";
0102   const OP_LOCATIONS                 = "locations";
0103   const OP_OPERATINGSYSTEMS          = "operatingsystems";
0104   const OP_OPERATINGSYSTEMFAMILIES   = "operatingsystemfamilies";
0105 
0106   /**
0107    * Current API version
0108    * 
0109    * @var string
0110    */
0111   protected $_apiVersion = '2011-02-25';
0112   
0113   /**
0114    * Subscription ID
0115    *
0116    * @var string
0117    */
0118   protected $_subscriptionId = '';
0119   
0120   /**
0121    * Management certificate path (.PEM)
0122    *
0123    * @var string
0124    */
0125   protected $_certificatePath = '';
0126   
0127   /**
0128    * Management certificate passphrase
0129    *
0130    * @var string
0131    */
0132   protected $_certificatePassphrase = '';
0133   
0134   /**
0135    * Zend_Http_Client channel used for communication with REST services
0136    * 
0137    * @var Zend_Http_Client
0138    */
0139   protected $_httpClientChannel = null; 
0140 
0141   /**
0142    * Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract instance
0143    * 
0144    * @var Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
0145    */
0146   protected $_retryPolicy = null;
0147   
0148   /**
0149    * Returns the last request ID
0150    * 
0151    * @var string
0152    */
0153   protected $_lastRequestId = null;
0154   
0155   /**
0156    * Creates a new Zend_Service_WindowsAzure_Management instance
0157    * 
0158    * @param string $subscriptionId Subscription ID
0159    * @param string $certificatePath Management certificate path (.PEM)
0160    * @param string $certificatePassphrase Management certificate passphrase
0161      * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
0162    */
0163   public function __construct(
0164     $subscriptionId,
0165     $certificatePath,
0166     $certificatePassphrase,
0167     Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null
0168   ) {
0169     $this->_subscriptionId = $subscriptionId;
0170     $this->_certificatePath = $certificatePath;
0171     $this->_certificatePassphrase = $certificatePassphrase;
0172     
0173     $this->_retryPolicy = $retryPolicy;
0174     if (is_null($this->_retryPolicy)) {
0175         $this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
0176     }
0177     
0178     // Setup default Zend_Http_Client channel
0179     $options = array(
0180         'adapter'       => 'Zend_Http_Client_Adapter_Socket',
0181         'ssltransport'  => 'ssl',
0182       'sslcert'       => $this->_certificatePath,
0183       'sslpassphrase' => $this->_certificatePassphrase,
0184       'sslusecontext' => true,
0185     );
0186     if (function_exists('curl_init')) {
0187       // Set cURL options if cURL is used afterwards
0188       $options['curloptions'] = array(
0189           CURLOPT_FOLLOWLOCATION => true,
0190           CURLOPT_TIMEOUT => 120,
0191       );
0192     }
0193     $this->_httpClientChannel = new Zend_Http_Client(null, $options);
0194   }
0195   
0196   /**
0197    * Set the HTTP client channel to use
0198    * 
0199    * @param Zend_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name.
0200    */
0201   public function setHttpClientChannel($adapterInstance = 'Zend_Http_Client_Adapter_Socket')
0202   {
0203     $this->_httpClientChannel->setAdapter($adapterInstance);
0204   }
0205   
0206     /**
0207      * Retrieve HTTP client channel
0208      * 
0209      * @return Zend_Http_Client_Adapter_Interface
0210      */
0211     public function getHttpClientChannel()
0212     {
0213         return $this->_httpClientChannel;
0214     }
0215   
0216   /**
0217    * Returns the Windows Azure subscription ID
0218    * 
0219    * @return string
0220    */
0221   public function getSubscriptionId()
0222   {
0223     return $this->_subscriptionId;
0224   }
0225   
0226   /**
0227    * Returns the last request ID.
0228    * 
0229    * @return string
0230    */
0231   public function getLastRequestId()
0232   {
0233     return $this->_lastRequestId;
0234   }
0235   
0236   /**
0237    * Get base URL for creating requests
0238    *
0239    * @return string
0240    */
0241   public function getBaseUrl()
0242   {
0243     return self::URL_MANAGEMENT . '/' . $this->_subscriptionId;
0244   }
0245   
0246   /**
0247    * Perform request using Zend_Http_Client channel
0248    *
0249    * @param string $path Path
0250    * @param string $queryString Query string
0251    * @param string $httpVerb HTTP verb the request will use
0252    * @param array $headers x-ms headers to add
0253    * @param mixed $rawData Optional RAW HTTP data to be sent over the wire
0254    * @return Zend_Http_Response
0255    */
0256   protected function _performRequest(
0257     $path = '/',
0258     $queryString = '',
0259     $httpVerb = Zend_Http_Client::GET,
0260     $headers = array(),
0261     $rawData = null
0262   ) {
0263       // Clean path
0264     if (strpos($path, '/') !== 0) {
0265       $path = '/' . $path;
0266     }
0267       
0268     // Clean headers
0269     if (is_null($headers)) {
0270         $headers = array();
0271     }
0272     
0273     // Ensure cUrl will also work correctly:
0274     //  - disable Content-Type if required
0275     //  - disable Expect: 100 Continue
0276     if (!isset($headers["Content-Type"])) {
0277       $headers["Content-Type"] = '';
0278     }
0279     //$headers["Expect"] = '';
0280 
0281     // Add version header
0282     $headers['x-ms-version'] = $this->_apiVersion;
0283         
0284     // URL encoding
0285     $path           = self::urlencode($path);
0286     $queryString    = self::urlencode($queryString);
0287 
0288     // Generate URL and sign request
0289     $requestUrl     = $this->getBaseUrl() . $path . $queryString;
0290     $requestHeaders = $headers;
0291 
0292     // Prepare request 
0293     $this->_httpClientChannel->resetParameters(true);
0294     $this->_httpClientChannel->setUri($requestUrl);
0295     $this->_httpClientChannel->setHeaders($requestHeaders);
0296     $this->_httpClientChannel->setRawData($rawData);
0297 
0298     // Execute request
0299     $response = $this->_retryPolicy->execute(
0300         array($this->_httpClientChannel, 'request'),
0301         array($httpVerb)
0302     );
0303     
0304     // Store request id
0305     $this->_lastRequestId = $response->getHeader('x-ms-request-id');
0306     
0307     return $response;
0308   }
0309   
0310   /** 
0311    * Parse result from Zend_Http_Response
0312    *
0313    * @param Zend_Http_Response $response Response from HTTP call
0314    * @return object
0315    * @throws Zend_Service_WindowsAzure_Exception
0316    */
0317   protected function _parseResponse(Zend_Http_Response $response = null)
0318   {
0319     if (is_null($response)) {
0320       // require_once 'Zend/Service/WindowsAzure/Exception.php';
0321       throw new Zend_Service_WindowsAzure_Exception('Response should not be null.');
0322     }
0323     
0324         $xml = Zend_Xml_Security::scan($response->getBody());
0325         
0326         if ($xml !== false) {
0327             // Fetch all namespaces 
0328             $namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true)); 
0329             
0330             // Register all namespace prefixes
0331             foreach ($namespaces as $prefix => $ns) { 
0332                 if ($prefix != '') {
0333                     $xml->registerXPathNamespace($prefix, $ns);
0334                 } 
0335             } 
0336         }
0337         
0338         return $xml;
0339   }
0340   
0341   /**
0342    * URL encode function
0343    * 
0344    * @param  string $value Value to encode
0345    * @return string        Encoded value
0346    */
0347   public static function urlencode($value)
0348   {
0349       return str_replace(' ', '%20', $value);
0350   }
0351   
0352     /**
0353      * Builds a query string from an array of elements
0354      * 
0355      * @param array     Array of elements
0356      * @return string   Assembled query string
0357      */
0358     public static function createQueryStringFromArray($queryString)
0359     {
0360       return count($queryString) > 0 ? '?' . implode('&', $queryString) : '';
0361     }
0362     
0363   /**
0364    * Get error message from Zend_Http_Response
0365    *
0366    * @param Zend_Http_Response $response Repsonse
0367    * @param string $alternativeError Alternative error message
0368    * @return string
0369    */
0370   protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.')
0371   {
0372     $response = $this->_parseResponse($response);
0373     if ($response && $response->Message) {
0374       return (string)$response->Message;
0375     } else {
0376       return $alternativeError;
0377     }
0378   }
0379     
0380     /**
0381      * The Get Operation Status operation returns the status of the specified operation.
0382      * After calling an asynchronous operation, you can call Get Operation Status to
0383      * determine whether the operation has succeed, failed, or is still in progress.
0384      *
0385      * @param string $requestId The request ID. If omitted, the last request ID will be used.
0386      * @return Zend_Service_WindowsAzure_Management_OperationStatusInstance
0387      * @throws Zend_Service_WindowsAzure_Management_Exception
0388      */
0389     public function getOperationStatus($requestId = '')
0390     {
0391       if ($requestId == '') {
0392         $requestId = $this->getLastRequestId();
0393       }
0394       
0395       $response = $this->_performRequest(self::OP_OPERATIONS . '/' . $requestId);
0396 
0397       if ($response->isSuccessful()) {
0398       $result = $this->_parseResponse($response);
0399 
0400       if (!is_null($result)) {
0401         return new Zend_Service_WindowsAzure_Management_OperationStatusInstance(
0402           (string)$result->ID,
0403           (string)$result->Status,
0404           ($result->Error ? (string)$result->Error->Code : ''),
0405           ($result->Error ? (string)$result->Error->Message : '')
0406         );
0407       }
0408       return null;
0409     } else {
0410       // require_once 'Zend/Service/Management/Exception.php';
0411       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0412     }
0413     }
0414     
0415 
0416     
0417     /**
0418      * The List Subscription Operations operation returns a list of create, update,
0419      * and delete operations that were performed on a subscription during the specified timeframe.
0420      * Documentation on the parameters can be found at http://msdn.microsoft.com/en-us/library/gg715318.aspx.
0421      *
0422      * @param string $startTime The start of the timeframe to begin listing subscription operations in UTC format. This parameter and the $endTime parameter indicate the timeframe to retrieve subscription operations. This parameter cannot indicate a start date of more than 90 days in the past.
0423      * @param string $endTime The end of the timeframe to begin listing subscription operations in UTC format. This parameter and the $startTime parameter indicate the timeframe to retrieve subscription operations. 
0424      * @param string $objectIdFilter Returns subscription operations only for the specified object type and object ID. 
0425      * @param string $operationResultFilter Returns subscription operations only for the specified result status, either Succeeded, Failed, or InProgress.
0426      * @param string $continuationToken Internal usage.
0427      * @return array Array of Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance
0428      * @throws Zend_Service_WindowsAzure_Management_Exception
0429      */
0430     public function listSubscriptionOperations($startTime, $endTime, $objectIdFilter = null, $operationResultFilter = null, $continuationToken = null)
0431     {
0432       if ($startTime == '' || is_null($startTime)) {
0433       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0434         throw new Zend_Service_WindowsAzure_Management_Exception('Start time should be specified.');
0435       }
0436       if ($endTime == '' || is_null($endTime)) {
0437       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0438         throw new Zend_Service_WindowsAzure_Management_Exception('End time should be specified.');
0439       }
0440       if ($operationResultFilter != '' && !is_null($operationResultFilter)) {
0441           $operationResultFilter = strtolower($operationResultFilter);
0442         if ($operationResultFilter != 'succeeded' && $operationResultFilter != 'failed' && $operationResultFilter != 'inprogress') {
0443         // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0444           throw new Zend_Service_WindowsAzure_Management_Exception('OperationResultFilter should be succeeded|failed|inprogress.');
0445         }
0446       }
0447       
0448       $parameters = array();
0449       $parameters[] = 'StartTime=' . $startTime;
0450       $parameters[] = 'EndTime=' . $endTime;
0451       if ($objectIdFilter != '' && !is_null($objectIdFilter)) {
0452         $parameters[] = 'ObjectIdFilter=' . $objectIdFilter;
0453       }
0454       if ($operationResultFilter != '' && !is_null($operationResultFilter)) {
0455         $parameters[] = 'OperationResultFilter=' . ucfirst($operationResultFilter);
0456       }
0457       if ($continuationToken != '' && !is_null($continuationToken)) {
0458         $parameters[] = 'ContinuationToken=' . $continuationToken;
0459       }
0460       
0461       $response = $this->_performRequest(self::OP_OPERATIONS, '?' . implode('&', $parameters));
0462 
0463       if ($response->isSuccessful()) {
0464       $result = $this->_parseResponse($response);
0465       $namespaces = $result->getDocNamespaces(); 
0466         $result->registerXPathNamespace('__empty_ns', $namespaces['']);
0467  
0468       $xmlOperations = $result->xpath('//__empty_ns:SubscriptionOperation');
0469       
0470         // Create return value
0471         $returnValue = array();       
0472         foreach ($xmlOperations as $xmlOperation) {
0473           // Create operation instance
0474           $operation = new Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance(
0475             $xmlOperation->OperationId,
0476             $xmlOperation->OperationObjectId,
0477             $xmlOperation->OperationName,
0478             array(),
0479             (array)$xmlOperation->OperationCaller,
0480             (array)$xmlOperation->OperationStatus
0481           );
0482           
0483           // Parse parameters
0484           $xmlOperation->registerXPathNamespace('__empty_ns', $namespaces['']); 
0485           $xmlParameters = $xmlOperation->xpath('.//__empty_ns:OperationParameter');
0486           foreach ($xmlParameters as $xmlParameter) {
0487             $xmlParameterDetails = $xmlParameter->children('http://schemas.datacontract.org/2004/07/Microsoft.Samples.WindowsAzure.ServiceManagement');
0488             $operation->addOperationParameter((string)$xmlParameterDetails->Name, (string)$xmlParameterDetails->Value);
0489           }
0490           
0491             // Add to result
0492             $returnValue[] = $operation;
0493         }
0494         
0495       // More data?
0496         if (!is_null($result->ContinuationToken) && $result->ContinuationToken != '') {
0497           $returnValue = array_merge($returnValue, $this->listSubscriptionOperations($startTime, $endTime, $objectIdFilter, $operationResultFilter, (string)$result->ContinuationToken));
0498         }
0499         
0500         // Return
0501         return $returnValue;
0502     } else {
0503       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0504       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0505     }
0506     }
0507     
0508     /**
0509      * Wait for an operation to complete
0510      * 
0511      * @param string $requestId The request ID. If omitted, the last request ID will be used.
0512      * @param int $sleepInterval Sleep interval in milliseconds.
0513      * @return Zend_Service_WindowsAzure_Management_OperationStatusInstance
0514      * @throws Zend_Service_WindowsAzure_Management_Exception
0515      */
0516     public function waitForOperation($requestId = '', $sleepInterval = 250)
0517     {
0518       if ($requestId == '') {
0519         $requestId = $this->getLastRequestId();
0520       }
0521       if ($requestId == '' || is_null($requestId)) {
0522         return null;
0523       }
0524 
0525     $status = $this->getOperationStatus($requestId);
0526     while ($status->Status == 'InProgress') {
0527       $status = $this->getOperationStatus($requestId);
0528       usleep($sleepInterval);
0529     }
0530     
0531     return $status;
0532     }
0533     
0534   /**
0535    * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance for the current account
0536    *
0537    * @param string $serviceName the service name to create a storage client for.
0538    * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
0539    * @return Zend_Service_WindowsAzure_Storage_Blob
0540    */
0541   public function createBlobClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
0542   {
0543     if ($serviceName == '' || is_null($serviceName)) {
0544         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0545       }
0546       
0547       $storageKeys = $this->getStorageAccountKeys($serviceName);
0548       
0549     
0550     
0551     return new Zend_Service_WindowsAzure_Storage_Blob(
0552       Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB,
0553       $serviceName,
0554       $storageKeys[0],
0555       false,
0556       $retryPolicy
0557     );
0558   }
0559   
0560   /**
0561    * Creates a new Zend_Service_WindowsAzure_Storage_Table instance for the current account
0562    *
0563    * @param string $serviceName the service name to create a storage client for.
0564    * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
0565    * @return Zend_Service_WindowsAzure_Storage_Table
0566    */
0567   public function createTableClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
0568   {
0569     if ($serviceName == '' || is_null($serviceName)) {
0570       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0571         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0572       }
0573       
0574       $storageKeys = $this->getStorageAccountKeys($serviceName);
0575     
0576     return new Zend_Service_WindowsAzure_Storage_Table(
0577       Zend_Service_WindowsAzure_Storage::URL_CLOUD_TABLE,
0578       $serviceName,
0579       $storageKeys[0],
0580       false,
0581       $retryPolicy
0582     );
0583   }
0584   
0585   /**
0586    * Creates a new Zend_Service_WindowsAzure_Storage_Queue instance for the current account
0587    *
0588    * @param string $serviceName the service name to create a storage client for.
0589    * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
0590    * @return Zend_Service_WindowsAzure_Storage_Queue
0591    */
0592   public function createQueueClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
0593   {
0594     if ($serviceName == '' || is_null($serviceName)) {
0595       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0596         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0597       }
0598       
0599       $storageKeys = $this->getStorageAccountKeys($serviceName);
0600       
0601     // require_once 'Zend/Service/WindowsAzure/Storage/Queue.php';
0602     
0603     return new Zend_Service_WindowsAzure_Storage_Queue(
0604       Zend_Service_WindowsAzure_Storage::URL_CLOUD_QUEUE,
0605       $serviceName,
0606       $storageKeys[0],
0607       false,
0608       $retryPolicy
0609     );
0610   }
0611     
0612     /**
0613      * The List Storage Accounts operation lists the storage accounts available under
0614      * the current subscription.
0615      *
0616      * @return array An array of Zend_Service_WindowsAzure_Management_StorageServiceInstance
0617      */
0618     public function listStorageAccounts()
0619     {
0620       $response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS);
0621 
0622       if ($response->isSuccessful()) {
0623       $result = $this->_parseResponse($response);
0624       
0625         if (!$result->StorageService) {
0626         return array();
0627       }
0628         if (count($result->StorageService) > 1) {
0629             $xmlServices = $result->StorageService;
0630         } else {
0631             $xmlServices = array($result->StorageService);
0632         }
0633         
0634       $services = array();
0635       if (!is_null($xmlServices)) {       
0636         for ($i = 0; $i < count($xmlServices); $i++) {
0637           $services[] = new Zend_Service_WindowsAzure_Management_StorageServiceInstance(
0638               (string)$xmlServices[$i]->Url,
0639               (string)$xmlServices[$i]->ServiceName
0640           );
0641         }
0642       }
0643       return $services;
0644     } else {
0645       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0646     }
0647     }
0648     
0649     /**
0650      * The Get Storage Account Properties operation returns the system properties for the
0651      * specified storage account. These properties include: the address, description, and 
0652      * label of the storage account; and the name of the affinity group to which the service
0653      * belongs, or its geo-location if it is not part of an affinity group.
0654      *
0655      * @param string $serviceName The name of your service.
0656      * @return Zend_Service_WindowsAzure_Management_StorageServiceInstance
0657      * @throws Zend_Service_WindowsAzure_Management_Exception
0658      */
0659     public function getStorageAccountProperties($serviceName)
0660     {
0661       if ($serviceName == '' || is_null($serviceName)) {
0662         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0663       }
0664       
0665       $response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS . '/' . $serviceName);
0666 
0667       if ($response->isSuccessful()) {
0668       $xmlService = $this->_parseResponse($response);
0669 
0670       if (!is_null($xmlService)) {
0671         // require_once 'Zend/Service/WindowsAzure/Management/StorageServiceInstance.php';
0672         
0673         return new Zend_Service_WindowsAzure_Management_StorageServiceInstance(
0674           (string)$xmlService->Url,
0675           (string)$xmlService->ServiceName,
0676           (string)$xmlService->StorageServiceProperties->Description,
0677           (string)$xmlService->StorageServiceProperties->AffinityGroup,
0678           (string)$xmlService->StorageServiceProperties->Location,
0679           (string)$xmlService->StorageServiceProperties->Label
0680         );
0681       }
0682       return null;
0683     } else {
0684       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0685       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0686     }
0687     }
0688     
0689     /**
0690      * The Get Storage Keys operation returns the primary
0691      * and secondary access keys for the specified storage account.
0692      *
0693      * @param string $serviceName The name of your service.
0694      * @return array An array of strings
0695      * @throws Zend_Service_WindowsAzure_Management_Exception
0696      */
0697     public function getStorageAccountKeys($serviceName)
0698     {
0699       if ($serviceName == '' || is_null($serviceName)) {
0700       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0701         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0702       }
0703       
0704       $response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys');
0705 
0706       if ($response->isSuccessful()) {
0707       $xmlService = $this->_parseResponse($response);
0708 
0709       if (!is_null($xmlService)) {
0710         return array(
0711           (string)$xmlService->StorageServiceKeys->Primary,
0712           (string)$xmlService->StorageServiceKeys->Secondary
0713         );
0714       }
0715       return array();
0716     } else {
0717       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0718       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0719     }
0720     }
0721     
0722     /**
0723      * The Regenerate Keys operation regenerates the primary
0724      * or secondary access key for the specified storage account.
0725      *
0726      * @param string $serviceName The name of your service.
0727      * @param string $key     The key to regenerate (primary or secondary)
0728      * @return array An array of strings
0729      * @throws Zend_Service_WindowsAzure_Management_Exception
0730      */
0731     public function regenerateStorageAccountKey($serviceName, $key = 'primary')
0732     {
0733       if ($serviceName == '' || is_null($serviceName)) {
0734       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0735         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0736       }
0737       $key = strtolower($key);
0738       if ($key != 'primary' && $key != 'secondary') {
0739       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0740         throw new Zend_Service_WindowsAzure_Management_Exception('Key identifier should be primary|secondary.');
0741       }
0742       
0743       $response = $this->_performRequest(
0744         self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys', '?action=regenerate',
0745         Zend_Http_Client::POST,
0746         array('Content-Type' => 'application/xml'),
0747         '<?xml version="1.0" encoding="utf-8"?>
0748              <RegenerateKeys xmlns="http://schemas.microsoft.com/windowsazure">
0749                <KeyType>' . ucfirst($key) . '</KeyType>
0750              </RegenerateKeys>');
0751 
0752       if ($response->isSuccessful()) {
0753       $xmlService = $this->_parseResponse($response);
0754 
0755       if (!is_null($xmlService)) {
0756         return array(
0757           (string)$xmlService->StorageServiceKeys->Primary,
0758           (string)$xmlService->StorageServiceKeys->Secondary
0759         );
0760       }
0761       return array();
0762     } else {
0763       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0764       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0765     }
0766     }
0767     
0768     /**
0769      * The List Hosted Services operation lists the hosted services available
0770      * under the current subscription.
0771      *
0772      * @return array An array of Zend_Service_WindowsAzure_Management_HostedServiceInstance
0773      * @throws Zend_Service_WindowsAzure_Management_Exception
0774      */
0775     public function listHostedServices()
0776     {
0777       $response = $this->_performRequest(self::OP_HOSTED_SERVICES);
0778 
0779       if ($response->isSuccessful()) {
0780       $result = $this->_parseResponse($response);
0781       
0782         if (!$result->HostedService) {
0783         return array();
0784       }
0785         if (count($result->HostedService) > 1) {
0786             $xmlServices = $result->HostedService;
0787         } else {
0788             $xmlServices = array($result->HostedService);
0789         }
0790         
0791       $services = array();
0792       if (!is_null($xmlServices)) { 
0793         
0794         for ($i = 0; $i < count($xmlServices); $i++) {
0795           $services[] = new Zend_Service_WindowsAzure_Management_HostedServiceInstance(
0796               (string)$xmlServices[$i]->Url,
0797               (string)$xmlServices[$i]->ServiceName
0798           );
0799         }
0800       }
0801       return $services;
0802     } else {
0803       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0804       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0805     }
0806     }
0807     
0808     /**
0809      * The Create Hosted Service operation creates a new hosted service in Windows Azure.
0810      * 
0811      * @param string $serviceName A name for the hosted service that is unique to the subscription.
0812      * @param string $label A label for the hosted service. The label may be up to 100 characters in length.
0813      * @param string $description A description for the hosted service. The description may be up to 1024 characters in length.
0814      * @param string $location Required if AffinityGroup is not specified. The location where the hosted service will be created. 
0815      * @param string $affinityGroup Required if Location is not specified. The name of an existing affinity group associated with this subscription.
0816      */
0817     public function createHostedService($serviceName, $label, $description = '', $location = null, $affinityGroup = null)
0818     {
0819       if ($serviceName == '' || is_null($serviceName)) {
0820       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0821         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0822       }
0823       if ($label == '' || is_null($label)) {
0824       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0825         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
0826       }
0827         if (strlen($label) > 100) {
0828       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0829         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
0830       }
0831         if (strlen($description) > 1024) {
0832       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0833         throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.');
0834       }
0835       if ( (is_null($location) && is_null($affinityGroup)) || (!is_null($location) && !is_null($affinityGroup)) ) {
0836       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0837         throw new Zend_Service_WindowsAzure_Management_Exception('Please specify a location -or- an affinity group for the service.');
0838       }
0839       
0840       $locationOrAffinityGroup = is_null($location)
0841         ? '<AffinityGroup>' . $affinityGroup . '</AffinityGroup>'
0842         : '<Location>' . $location . '</Location>';
0843       
0844         $response = $this->_performRequest(self::OP_HOSTED_SERVICES, '',
0845         Zend_Http_Client::POST,
0846         array('Content-Type' => 'application/xml; charset=utf-8'),
0847         '<CreateHostedService xmlns="http://schemas.microsoft.com/windowsazure"><ServiceName>' . $serviceName . '</ServiceName><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description>' . $locationOrAffinityGroup . '</CreateHostedService>');
0848   
0849       if (!$response->isSuccessful()) {
0850       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0851       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0852     }
0853     }
0854     
0855     /**
0856      * The Update Hosted Service operation updates the label and/or the description for a hosted service in Windows Azure.
0857      * 
0858      * @param string $serviceName A name for the hosted service that is unique to the subscription.
0859      * @param string $label A label for the hosted service. The label may be up to 100 characters in length.
0860      * @param string $description A description for the hosted service. The description may be up to 1024 characters in length.
0861      */
0862     public function updateHostedService($serviceName, $label, $description = '')
0863     {
0864       if ($serviceName == '' || is_null($serviceName)) {
0865       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0866         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0867       }
0868       if ($label == '' || is_null($label)) {
0869       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0870         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
0871       }
0872         if (strlen($label) > 100) {
0873       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0874         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
0875       }
0876       
0877         $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '',
0878         Zend_Http_Client::PUT,
0879         array('Content-Type' => 'application/xml; charset=utf-8'),
0880         '<UpdateHostedService xmlns="http://schemas.microsoft.com/windowsazure"><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description></UpdateHostedService>');
0881   
0882       if (!$response->isSuccessful()) {
0883       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0884       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0885     }
0886     }
0887     
0888     /**
0889      * The Delete Hosted Service operation deletes the specified hosted service in Windows Azure.
0890      * 
0891      * @param string $serviceName A name for the hosted service that is unique to the subscription.
0892      */
0893     public function deleteHostedService($serviceName)
0894     {
0895       if ($serviceName == '' || is_null($serviceName)) {
0896       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0897         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0898       }
0899       
0900         $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '', Zend_Http_Client::DELETE);
0901   
0902       if (!$response->isSuccessful()) {
0903       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0904       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0905     }
0906     }
0907     
0908     /**
0909      * The Get Hosted Service Properties operation retrieves system properties
0910      * for the specified hosted service. These properties include the service
0911      * name and service type; the name of the affinity group to which the service
0912      * belongs, or its location if it is not part of an affinity group; and
0913      * optionally, information on the service's deployments.
0914      *
0915      * @param string $serviceName The name of your service.
0916      * @return Zend_Service_WindowsAzure_Management_HostedServiceInstance
0917      * @throws Zend_Service_WindowsAzure_Management_Exception
0918      */
0919     public function getHostedServiceProperties($serviceName)
0920     {
0921       if ($serviceName == '' || is_null($serviceName)) {
0922       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0923         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0924       }
0925       
0926       $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '?embed-detail=true');
0927 
0928       if ($response->isSuccessful()) {
0929       $xmlService = $this->_parseResponse($response);
0930 
0931       if (!is_null($xmlService)) {
0932         
0933         $returnValue = new Zend_Service_WindowsAzure_Management_HostedServiceInstance(
0934           (string)$xmlService->Url,
0935           (string)$xmlService->ServiceName,
0936           (string)$xmlService->HostedServiceProperties->Description,
0937           (string)$xmlService->HostedServiceProperties->AffinityGroup,
0938           (string)$xmlService->HostedServiceProperties->Location,
0939           (string)$xmlService->HostedServiceProperties->Label
0940         );
0941         
0942         // Deployments
0943           if (count($xmlService->Deployments->Deployment) > 1) {
0944               $xmlServices = $xmlService->Deployments->Deployment;
0945           } else {
0946               $xmlServices = array($xmlService->Deployments->Deployment);
0947           }
0948           
0949           $deployments = array();
0950           foreach ($xmlServices as $xmlDeployment) {
0951           $deployments[] = $this->_convertXmlElementToDeploymentInstance($xmlDeployment);
0952           }
0953         $returnValue->Deployments = $deployments;
0954         
0955         return $returnValue;
0956       }
0957       return null;
0958     } else {
0959       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0960       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
0961     }
0962     }
0963 
0964     /**
0965      * The Create Deployment operation uploads a new service package
0966      * and creates a new deployment on staging or production.
0967      * 
0968      * @param string $serviceName   The service name
0969      * @param string $deploymentSlot  The deployment slot (production or staging)
0970    * @param string $name              The name for the deployment. The deployment ID as listed on the Windows Azure management portal must be unique among other deployments for the hosted service.
0971    * @param string $label             A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription.
0972    * @param string $packageUrl        The service configuration file for the deployment.
0973    * @param string $configuration     A label for this deployment, up to 100 characters in length.
0974    * @param boolean $startDeployment  Indicates whether to start the deployment immediately after it is created.
0975    * @param boolean $treatWarningsAsErrors Indicates whether to treat package validation warnings as errors.
0976      * @throws Zend_Service_WindowsAzure_Management_Exception
0977      */
0978     public function createDeployment($serviceName, $deploymentSlot, $name, $label, $packageUrl, $configuration, $startDeployment = false, $treatWarningsAsErrors = false)
0979     {
0980         if ($serviceName == '' || is_null($serviceName)) {
0981       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0982         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
0983       }
0984       $deploymentSlot = strtolower($deploymentSlot);
0985       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
0986       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0987         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
0988       }
0989       if ($name == '' || is_null($name)) {
0990       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0991         throw new Zend_Service_WindowsAzure_Management_Exception('Name should be specified.');
0992       }
0993       if ($label == '' || is_null($label)) {
0994       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0995         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
0996       }
0997         if (strlen($label) > 100) {
0998       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
0999         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
1000       }
1001       if ($packageUrl == '' || is_null($packageUrl)) {
1002       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1003         throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.');
1004       }
1005       if ($configuration == '' || is_null($configuration)) {
1006       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1007         throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.');
1008       }
1009       
1010       if (@file_exists($configuration)) {
1011         $configuration = utf8_decode(file_get_contents($configuration));
1012       }
1013       
1014       // Clean up the configuration
1015       $conformingConfiguration = $this->_cleanConfiguration($configuration);
1016       
1017       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1018         $response = $this->_performRequest($operationUrl, '',
1019         Zend_Http_Client::POST,
1020         array('Content-Type' => 'application/xml; charset=utf-8'),
1021         '<CreateDeployment xmlns="http://schemas.microsoft.com/windowsazure"><Name>' . $name . '</Name><PackageUrl>' . $packageUrl . '</PackageUrl><Label>' . base64_encode($label) . '</Label><Configuration>' . base64_encode($conformingConfiguration) . '</Configuration><StartDeployment>' . ($startDeployment ? 'true' : 'false') . '</StartDeployment><TreatWarningsAsError>' . ($treatWarningsAsErrors ? 'true' : 'false') . '</TreatWarningsAsError></CreateDeployment>');
1022   
1023       if (!$response->isSuccessful()) {
1024       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1025       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1026     }     
1027     }
1028     
1029     /**
1030      * The Get Deployment operation returns configuration information, status,
1031      * and system properties for the specified deployment.
1032      * 
1033      * @param string $serviceName   The service name
1034      * @param string $deploymentSlot  The deployment slot (production or staging)
1035      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
1036      * @throws Zend_Service_WindowsAzure_Management_Exception
1037      */
1038     public function getDeploymentBySlot($serviceName, $deploymentSlot)
1039     {
1040         if ($serviceName == '' || is_null($serviceName)) {
1041       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1042         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1043       }
1044       $deploymentSlot = strtolower($deploymentSlot);
1045       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1046       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1047         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1048       }
1049       
1050       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1051       return $this->_getDeployment($operationUrl);
1052     }
1053     
1054     /**
1055      * The Get Deployment operation returns configuration information, status,
1056      * and system properties for the specified deployment.
1057      * 
1058      * @param string $serviceName   The service name
1059      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1060      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
1061      * @throws Zend_Service_WindowsAzure_Management_Exception
1062      */
1063     public function getDeploymentByDeploymentId($serviceName, $deploymentId)
1064     {
1065         if ($serviceName == '' || is_null($serviceName)) {
1066       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1067         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1068       }
1069         if ($deploymentId == '' || is_null($deploymentId)) {
1070       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1071         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1072       }
1073       
1074       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
1075       return $this->_getDeployment($operationUrl);
1076     }
1077     
1078     /**
1079      * The Get Deployment operation returns configuration information, status,
1080      * and system properties for the specified deployment.
1081      * 
1082      * @param string $operationUrl    The operation url
1083      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
1084      * @throws Zend_Service_WindowsAzure_Management_Exception
1085      */
1086     protected function _getDeployment($operationUrl)
1087     {
1088         $response = $this->_performRequest($operationUrl);
1089 
1090       if ($response->isSuccessful()) {
1091       $xmlService = $this->_parseResponse($response);
1092       
1093       return $this->_convertXmlElementToDeploymentInstance($xmlService);
1094     } else {
1095       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1096       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1097     }
1098     }
1099     
1100     /**
1101      * The Swap Deployment operation initiates a virtual IP swap between
1102      * the staging and production deployment environments for a service.
1103      * If the service is currently running in the staging environment,
1104      * it will be swapped to the production environment. If it is running
1105      * in the production environment, it will be swapped to staging.
1106      * 
1107      * @param string $serviceName The service name.
1108      * @param string $productionDeploymentName The name of the production deployment.
1109      * @param string $sourceDeploymentName The name of the source deployment.
1110      * @throws Zend_Service_WindowsAzure_Management_Exception
1111      */
1112     public function swapDeployment($serviceName, $productionDeploymentName, $sourceDeploymentName)
1113     {
1114       if ($serviceName == '' || is_null($serviceName)) {
1115       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1116         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1117       }
1118       if ($productionDeploymentName == '' || is_null($productionDeploymentName)) {
1119       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1120         throw new Zend_Service_WindowsAzure_Management_Exception('Production Deployment ID should be specified.');
1121       }
1122       if ($sourceDeploymentName == '' || is_null($sourceDeploymentName)) {
1123       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1124         throw new Zend_Service_WindowsAzure_Management_Exception('Source Deployment ID should be specified.');
1125       }
1126       
1127       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName;
1128         $response = $this->_performRequest($operationUrl, '',
1129         Zend_Http_Client::POST,
1130         array('Content-Type' => 'application/xml; charset=utf-8'),
1131         '<Swap xmlns="http://schemas.microsoft.com/windowsazure"><Production>' . $productionDeploymentName . '</Production><SourceDeployment>' . $sourceDeploymentName . '</SourceDeployment></Swap>');
1132         
1133       if (!$response->isSuccessful()) {
1134       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1135       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1136     }     
1137     }
1138     
1139     /**
1140      * The Delete Deployment operation deletes the specified deployment.
1141      * 
1142      * @param string $serviceName   The service name
1143      * @param string $deploymentSlot  The deployment slot (production or staging)
1144      * @throws Zend_Service_WindowsAzure_Management_Exception
1145      */
1146     public function deleteDeploymentBySlot($serviceName, $deploymentSlot)
1147     {
1148         if ($serviceName == '' || is_null($serviceName)) {
1149       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1150         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1151       }
1152       $deploymentSlot = strtolower($deploymentSlot);
1153       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1154       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1155         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1156       }
1157       
1158       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1159       return $this->_deleteDeployment($operationUrl);
1160     }
1161     
1162     /**
1163      * The Delete Deployment operation deletes the specified deployment.
1164      * 
1165      * @param string $serviceName   The service name
1166      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1167      * @throws Zend_Service_WindowsAzure_Management_Exception
1168      */
1169     public function deleteDeploymentByDeploymentId($serviceName, $deploymentId)
1170     {
1171         if ($serviceName == '' || is_null($serviceName)) {
1172       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1173         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1174       }
1175       if ($deploymentId == '' || is_null($deploymentId)) {
1176       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1177         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1178       }
1179       
1180       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
1181       return $this->_deleteDeployment($operationUrl);
1182     }
1183     
1184     /**
1185      * The Delete Deployment operation deletes the specified deployment.
1186      * 
1187      * @param string $operationUrl    The operation url
1188      * @throws Zend_Service_WindowsAzure_Management_Exception
1189      */
1190     protected function _deleteDeployment($operationUrl)
1191     {
1192         $response = $this->_performRequest($operationUrl, '', Zend_Http_Client::DELETE);
1193        
1194       if (!$response->isSuccessful()) {
1195       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1196       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1197     }
1198     }
1199     
1200     /**
1201      * The Update Deployment Status operation initiates a change in deployment status.
1202      * 
1203      * @param string $serviceName   The service name
1204      * @param string $deploymentSlot  The deployment slot (production or staging)
1205      * @param string $status            The deployment status (running|suspended)
1206      * @throws Zend_Service_WindowsAzure_Management_Exception
1207      */
1208     public function updateDeploymentStatusBySlot($serviceName, $deploymentSlot, $status = 'running')
1209     {
1210         if ($serviceName == '' || is_null($serviceName)) {
1211       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1212         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1213       }
1214       $deploymentSlot = strtolower($deploymentSlot);
1215       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1216       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1217         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1218       }
1219       $status = strtolower($status);
1220       if ($status != 'running' && $status != 'suspended') {
1221       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1222         throw new Zend_Service_WindowsAzure_Management_Exception('Status should be running|suspended.');
1223       }
1224       
1225       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1226       return $this->_updateDeploymentStatus($operationUrl, $status);
1227     }
1228     
1229     /**
1230      * The Update Deployment Status operation initiates a change in deployment status.
1231      * 
1232      * @param string $serviceName   The service name
1233      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1234      * @param string $status            The deployment status (running|suspended)
1235      * @throws Zend_Service_WindowsAzure_Management_Exception
1236      */
1237     public function updateDeploymentStatusByDeploymentId($serviceName, $deploymentId, $status = 'running')
1238     {
1239         if ($serviceName == '' || is_null($serviceName)) {
1240       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1241         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1242       }
1243       if ($deploymentId == '' || is_null($deploymentId)) {
1244       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1245         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1246       }
1247         $status = strtolower($status);
1248       if ($status != 'running' && $status != 'suspended') {
1249       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1250         throw new Zend_Service_WindowsAzure_Management_Exception('Status should be running|suspended.');
1251       }
1252       
1253       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
1254       return $this->_updateDeploymentStatus($operationUrl, $status);
1255     }
1256     
1257     /**
1258      * The Update Deployment Status operation initiates a change in deployment status.
1259      * 
1260      * @param string $operationUrl    The operation url
1261      * @param string $status            The deployment status (running|suspended)
1262      * @throws Zend_Service_WindowsAzure_Management_Exception
1263      */
1264     protected function _updateDeploymentStatus($operationUrl, $status = 'running')
1265     {
1266         $response = $this->_performRequest($operationUrl . '/', '?comp=status',
1267         Zend_Http_Client::POST,
1268         array('Content-Type' => 'application/xml; charset=utf-8'),
1269         '<UpdateDeploymentStatus xmlns="http://schemas.microsoft.com/windowsazure"><Status>' . ucfirst($status) . '</Status></UpdateDeploymentStatus>');
1270         
1271       if (!$response->isSuccessful()) {
1272       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1273       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1274     }
1275     }
1276     
1277     /**
1278      * Converts an XmlElement into a Zend_Service_WindowsAzure_Management_DeploymentInstance
1279      * 
1280      * @param object $xmlService The XML Element
1281      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
1282      * @throws Zend_Service_WindowsAzure_Management_Exception
1283      */
1284     protected function _convertXmlElementToDeploymentInstance($xmlService)
1285     {
1286     if (!is_null($xmlService)) {
1287       
1288       $returnValue = new Zend_Service_WindowsAzure_Management_DeploymentInstance(
1289         (string)$xmlService->Name,
1290         (string)$xmlService->DeploymentSlot,
1291         (string)$xmlService->PrivateID,
1292         (string)$xmlService->Label,
1293         (string)$xmlService->Url,
1294         (string)$xmlService->Configuration,
1295         (string)$xmlService->Status,
1296         (string)$xmlService->UpgradeStatus,
1297         (string)$xmlService->UpgradeType,
1298         (string)$xmlService->CurrentUpgradeDomainState,
1299         (string)$xmlService->CurrentUpgradeDomain,
1300         (string)$xmlService->UpgradeDomainCount
1301       );
1302         
1303       // Append role instances
1304       if ($xmlService->RoleInstanceList && $xmlService->RoleInstanceList->RoleInstance) {
1305         $xmlRoleInstances = $xmlService->RoleInstanceList->RoleInstance;
1306         if (count($xmlService->RoleInstanceList->RoleInstance) == 1) {
1307               $xmlRoleInstances = array($xmlService->RoleInstanceList->RoleInstance);
1308           }
1309             
1310         $roleInstances = array();
1311         if (!is_null($xmlRoleInstances)) {        
1312           for ($i = 0; $i < count($xmlRoleInstances); $i++) {
1313             $roleInstances[] = array(
1314                 'rolename' => (string)$xmlRoleInstances[$i]->RoleName,
1315                 'instancename' => (string)$xmlRoleInstances[$i]->InstanceName,
1316                 'instancestatus' => (string)$xmlRoleInstances[$i]->InstanceStatus
1317             );
1318           }
1319         }
1320         
1321         $returnValue->RoleInstanceList = $roleInstances;
1322       }
1323       
1324       // Append roles
1325       if ($xmlService->RoleList && $xmlService->RoleList->Role) {
1326         $xmlRoles = $xmlService->RoleList->Role;
1327         if (count($xmlService->RoleList->Role) == 1) {
1328               $xmlRoles = array($xmlService->RoleList->Role);
1329           }
1330           
1331         $roles = array();
1332         if (!is_null($xmlRoles)) {        
1333           for ($i = 0; $i < count($xmlRoles); $i++) {
1334             $roles[] = array(
1335                 'rolename' => (string)$xmlRoles[$i]->RoleName,
1336                 'osversion' => (!is_null($xmlRoles[$i]->OsVersion) ? (string)$xmlRoles[$i]->OsVersion : (string)$xmlRoles[$i]->OperatingSystemVersion)          
1337             );
1338           }
1339         }
1340         $returnValue->RoleList = $roles;
1341       }
1342         
1343       return $returnValue;
1344     }
1345     return null;
1346     }
1347     
1348     /**
1349      * Updates a deployment's role instance count.
1350      * 
1351      * @param string $serviceName   The service name
1352      * @param string $deploymentSlot  The deployment slot (production or staging)
1353      * @param string|array $roleName  The role name
1354      * @param string|array $instanceCount The instance count
1355      * @throws Zend_Service_WindowsAzure_Management_Exception
1356      */
1357   public function setInstanceCountBySlot($serviceName, $deploymentSlot, $roleName, $instanceCount) {
1358       if ($serviceName == '' || is_null($serviceName)) {
1359       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1360         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1361       }
1362       $deploymentSlot = strtolower($deploymentSlot);
1363       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1364       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1365         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1366       }
1367       if ($roleName == '' || is_null($roleName)) {
1368       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1369         throw new Zend_Service_WindowsAzure_Management_Exception('Role name name should be specified.');
1370       }
1371       
1372     // Get configuration
1373     $deployment = $this->getDeploymentBySlot($serviceName, $deploymentSlot);
1374     $configuration = $deployment->Configuration;
1375     $configuration = $this->_updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration);
1376     
1377     // Update configuration
1378     $this->configureDeploymentBySlot($serviceName, $deploymentSlot, $configuration);    
1379   }
1380   
1381     /**
1382      * Updates a deployment's role instance count.
1383      * 
1384      * @param string $serviceName   The service name
1385      * @param string $deploymentSlot  The deployment slot (production or staging)
1386      * @param string|array $roleName  The role name
1387      * @param string|array $instanceCount The instance count
1388      * @throws Zend_Service_WindowsAzure_Management_Exception
1389      */
1390     public function setInstanceCountByDeploymentId($serviceName, $deploymentId, $roleName, $instanceCount)
1391     {
1392       if ($serviceName == '' || is_null($serviceName)) {
1393       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1394         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1395       }
1396         if ($deploymentId == '' || is_null($deploymentId)) {
1397       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1398         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1399       }
1400       if ($roleName == '' || is_null($roleName)) {
1401       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1402         throw new Zend_Service_WindowsAzure_Management_Exception('Role name name should be specified.');
1403       }
1404       
1405     // Get configuration
1406     $deployment = $this->getDeploymentByDeploymentId($serviceName, $deploymentId);
1407     $configuration = $deployment->Configuration;
1408     $configuration = $this->_updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration);
1409     
1410     // Update configuration
1411     $this->configureDeploymentByDeploymentId($serviceName, $deploymentId, $configuration);
1412     }
1413   
1414     /**
1415      * Updates instance count in configuration XML.
1416      * 
1417      * @param string|array $roleName      The role name
1418      * @param string|array $instanceCount   The instance count
1419      * @param string $configuration             XML configuration represented as a string
1420      * @throws Zend_Service_WindowsAzure_Management_Exception
1421      */
1422   protected function _updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration) {
1423       // Change variables
1424     if (!is_array($roleName)) {
1425       $roleName = array($roleName);
1426     }
1427     if (!is_array($instanceCount)) {
1428       $instanceCount = array($instanceCount);
1429     }
1430 
1431     $configuration = preg_replace('/(<\?xml[^?]+?)utf-16/i', '$1utf-8', $configuration);
1432     //$configuration = '<?xml version="1.0">' . substr($configuration, strpos($configuration, '>') + 2);
1433 
1434     $xml = Zend_Xml_Security::scan($configuration); 
1435     
1436     // http://www.php.net/manual/en/simplexmlelement.xpath.php#97818
1437     $namespaces = $xml->getDocNamespaces();
1438       $xml->registerXPathNamespace('__empty_ns', $namespaces['']); 
1439   
1440     for ($i = 0; $i < count($roleName); $i++) {
1441       $elements = $xml->xpath('//__empty_ns:Role[@name="' . $roleName[$i] . '"]/__empty_ns:Instances');
1442   
1443       if (count($elements) == 1) {
1444         $element = $elements[0];
1445         $element['count'] = $instanceCount[$i];
1446       } 
1447     }
1448     
1449     $configuration = $xml->asXML();
1450     //$configuration = preg_replace('/(<\?xml[^?]+?)utf-8/i', '$1utf-16', $configuration);
1451 
1452     return $configuration;
1453   }
1454     
1455     /**
1456      * The Change Deployment Configuration request may be specified as follows.
1457      * Note that you can change a deployment's configuration either by specifying the deployment
1458      * environment (staging or production), or by specifying the deployment's unique name. 
1459      * 
1460      * @param string $serviceName   The service name
1461      * @param string $deploymentSlot  The deployment slot (production or staging)
1462      * @param string $configuration     XML configuration represented as a string
1463      * @throws Zend_Service_WindowsAzure_Management_Exception
1464      */
1465     public function configureDeploymentBySlot($serviceName, $deploymentSlot, $configuration)
1466     {
1467         if ($serviceName == '' || is_null($serviceName)) {
1468       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1469         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1470       }
1471       $deploymentSlot = strtolower($deploymentSlot);
1472       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1473       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1474         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1475       }
1476       if ($configuration == '' || is_null($configuration)) {
1477       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1478         throw new Zend_Service_WindowsAzure_Management_Exception('Configuration name should be specified.');
1479       }
1480       
1481         if (@file_exists($configuration)) {
1482         $configuration = utf8_decode(file_get_contents($configuration));
1483       }
1484       
1485       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1486       return $this->_configureDeployment($operationUrl, $configuration);
1487     }
1488     
1489     /**
1490      * The Change Deployment Configuration request may be specified as follows.
1491      * Note that you can change a deployment's configuration either by specifying the deployment
1492      * environment (staging or production), or by specifying the deployment's unique name. 
1493      * 
1494      * @param string $serviceName   The service name
1495      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1496      * @param string $configuration     XML configuration represented as a string
1497      * @throws Zend_Service_WindowsAzure_Management_Exception
1498      */
1499     public function configureDeploymentByDeploymentId($serviceName, $deploymentId, $configuration)
1500     {
1501         if ($serviceName == '' || is_null($serviceName)) {
1502       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1503         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1504       }
1505       if ($deploymentId == '' || is_null($deploymentId)) {
1506       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1507         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1508       }
1509       if ($configuration == '' || is_null($configuration)) {
1510       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1511         throw new Zend_Service_WindowsAzure_Management_Exception('Configuration name should be specified.');
1512       }
1513       
1514         if (@file_exists($configuration)) {
1515         $configuration = utf8_decode(file_get_contents($configuration));
1516       }
1517       
1518       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
1519       return $this->_configureDeployment($operationUrl, $configuration);
1520     }
1521     
1522     /**
1523      * The Change Deployment Configuration request may be specified as follows.
1524      * Note that you can change a deployment's configuration either by specifying the deployment
1525      * environment (staging or production), or by specifying the deployment's unique name. 
1526      * 
1527      * @param string $operationUrl    The operation url
1528      * @param string $configuration     XML configuration represented as a string
1529      * @throws Zend_Service_WindowsAzure_Management_Exception
1530      */
1531     protected function _configureDeployment($operationUrl, $configuration)
1532     {
1533       // Clean up the configuration
1534       $conformingConfiguration = $this->_cleanConfiguration($configuration);
1535 
1536         $response = $this->_performRequest($operationUrl . '/', '?comp=config',
1537         Zend_Http_Client::POST,
1538         array('Content-Type' => 'application/xml; charset=utf-8'),
1539         '<ChangeConfiguration xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Configuration>' . base64_encode($conformingConfiguration) . '</Configuration></ChangeConfiguration>');
1540        
1541       if (!$response->isSuccessful()) {
1542       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1543       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1544     }
1545     }
1546     
1547     /**
1548      * The Upgrade Deployment operation initiates an upgrade.
1549      * 
1550      * @param string $serviceName   The service name
1551      * @param string $deploymentSlot  The deployment slot (production or staging)
1552    * @param string $label             A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription.
1553    * @param string $packageUrl        The service configuration file for the deployment.
1554    * @param string $configuration     A label for this deployment, up to 100 characters in length.
1555      * @param string $mode              The type of upgrade to initiate. Possible values are Auto or Manual.
1556      * @param string $roleToUpgrade     The name of the specific role to upgrade.
1557      * @throws Zend_Service_WindowsAzure_Management_Exception
1558      */
1559     public function upgradeDeploymentBySlot($serviceName, $deploymentSlot, $label, $packageUrl, $configuration, $mode = 'auto', $roleToUpgrade = null)
1560     {
1561         if ($serviceName == '' || is_null($serviceName)) {
1562       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1563         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1564       }
1565       $deploymentSlot = strtolower($deploymentSlot);
1566       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1567       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1568         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1569       }
1570       if ($label == '' || is_null($label)) {
1571       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1572         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
1573       }
1574         if (strlen($label) > 100) {
1575       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1576         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
1577       }
1578       if ($packageUrl == '' || is_null($packageUrl)) {
1579       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1580         throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.');
1581       }
1582       if ($configuration == '' || is_null($configuration)) {
1583       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1584         throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.');
1585       }
1586       $mode = strtolower($mode);
1587       if ($mode != 'auto' && $mode != 'manual') {
1588       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1589         throw new Zend_Service_WindowsAzure_Management_Exception('Mode should be auto|manual.');
1590       }
1591       
1592       if (@file_exists($configuration)) {
1593         $configuration = utf8_decode(file_get_contents($configuration));
1594       }
1595       
1596     $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1597       return $this->_upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade);    
1598     }
1599     
1600     /**
1601      * The Upgrade Deployment operation initiates an upgrade.
1602      * 
1603      * @param string $serviceName   The service name
1604      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1605    * @param string $label             A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription.
1606    * @param string $packageUrl        The service configuration file for the deployment.
1607    * @param string $configuration     A label for this deployment, up to 100 characters in length.
1608      * @param string $mode              The type of upgrade to initiate. Possible values are Auto or Manual.
1609      * @param string $roleToUpgrade     The name of the specific role to upgrade.
1610      * @throws Zend_Service_WindowsAzure_Management_Exception
1611      */
1612     public function upgradeDeploymentByDeploymentId($serviceName, $deploymentId, $label, $packageUrl, $configuration, $mode = 'auto', $roleToUpgrade = null)
1613     {
1614         if ($serviceName == '' || is_null($serviceName)) {
1615       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1616         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1617       }
1618       if ($deploymentId == '' || is_null($deploymentId)) {
1619       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1620         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1621       }
1622       if ($label == '' || is_null($label)) {
1623       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1624         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
1625       }
1626         if (strlen($label) > 100) {
1627       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1628         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
1629       }
1630       if ($packageUrl == '' || is_null($packageUrl)) {
1631       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1632         throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.');
1633       }
1634       if ($configuration == '' || is_null($configuration)) {
1635       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1636         throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.');
1637       }
1638       $mode = strtolower($mode);
1639       if ($mode != 'auto' && $mode != 'manual') {
1640       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1641         throw new Zend_Service_WindowsAzure_Management_Exception('Mode should be auto|manual.');
1642       }
1643       
1644       if (@file_exists($configuration)) {
1645         $configuration = utf8_decode(file_get_contents($configuration));
1646       }
1647       
1648     $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
1649       return $this->_upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade);    
1650     }
1651     
1652     
1653     /**
1654      * The Upgrade Deployment operation initiates an upgrade.
1655      * 
1656      * @param string $operationUrl    The operation url
1657    * @param string $label             A URL that refers to the location of the service package in the Blob service. The service package must be located in a storage account beneath the same subscription.
1658    * @param string $packageUrl        The service configuration file for the deployment.
1659    * @param string $configuration     A label for this deployment, up to 100 characters in length.
1660      * @param string $mode              The type of upgrade to initiate. Possible values are Auto or Manual.
1661      * @param string $roleToUpgrade     The name of the specific role to upgrade.
1662      * @throws Zend_Service_WindowsAzure_Management_Exception
1663      */
1664     protected function _upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade)
1665     {
1666       // Clean up the configuration
1667       $conformingConfiguration = $this->_cleanConfiguration($configuration);
1668       
1669         $response = $this->_performRequest($operationUrl . '/', '?comp=upgrade',
1670         Zend_Http_Client::POST,
1671         array('Content-Type' => 'application/xml; charset=utf-8'),
1672         '<UpgradeDeployment xmlns="http://schemas.microsoft.com/windowsazure"><Mode>' . ucfirst($mode) . '</Mode><PackageUrl>' . $packageUrl . '</PackageUrl><Configuration>' . base64_encode($conformingConfiguration) . '</Configuration><Label>' . base64_encode($label) . '</Label>' . (!is_null($roleToUpgrade) ? '<RoleToUpgrade>' . $roleToUpgrade . '</RoleToUpgrade>' : '') . '</UpgradeDeployment>');   
1673         
1674       if (!$response->isSuccessful()) {
1675       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1676       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1677     }
1678     }
1679     
1680     /**
1681      * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade.
1682      * 
1683      * @param string $serviceName   The service name
1684      * @param string $deploymentSlot  The deployment slot (production or staging)
1685    * @param int $upgradeDomain     An integer value that identifies the upgrade domain to walk. Upgrade domains are identified with a zero-based index: the first upgrade domain has an ID of 0, the second has an ID of 1, and so on.
1686      * @throws Zend_Service_WindowsAzure_Management_Exception
1687      */
1688     public function walkUpgradeDomainBySlot($serviceName, $deploymentSlot, $upgradeDomain = 0)
1689     {
1690         if ($serviceName == '' || is_null($serviceName)) {
1691       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1692         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1693       }
1694       $deploymentSlot = strtolower($deploymentSlot);
1695       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1696       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1697         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1698       }
1699       
1700     $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
1701       return $this->_walkUpgradeDomain($operationUrl, $upgradeDomain);    
1702     }
1703     
1704     /**
1705      * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade.
1706      * 
1707      * @param string $serviceName   The service name
1708      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1709    * @param int $upgradeDomain     An integer value that identifies the upgrade domain to walk. Upgrade domains are identified with a zero-based index: the first upgrade domain has an ID of 0, the second has an ID of 1, and so on.
1710      * @throws Zend_Service_WindowsAzure_Management_Exception
1711      */
1712     public function walkUpgradeDomainByDeploymentId($serviceName, $deploymentId, $upgradeDomain = 0)
1713     {
1714         if ($serviceName == '' || is_null($serviceName)) {
1715       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1716         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1717       }
1718       if ($deploymentId == '' || is_null($deploymentId)) {
1719       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1720         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1721       }
1722       
1723     $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
1724       return $this->_walkUpgradeDomain($operationUrl, $upgradeDomain);    
1725     }
1726     
1727     
1728     /**
1729      * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade.
1730      * 
1731      * @param string $operationUrl   The operation url
1732    * @param int $upgradeDomain     An integer value that identifies the upgrade domain to walk. Upgrade domains are identified with a zero-based index: the first upgrade domain has an ID of 0, the second has an ID of 1, and so on.
1733      * @throws Zend_Service_WindowsAzure_Management_Exception
1734      */
1735     protected function _walkUpgradeDomain($operationUrl, $upgradeDomain = 0)
1736     {
1737         $response = $this->_performRequest($operationUrl . '/', '?comp=walkupgradedomain',
1738         Zend_Http_Client::POST,
1739         array('Content-Type' => 'application/xml; charset=utf-8'),
1740         '<WalkUpgradeDomain xmlns="http://schemas.microsoft.com/windowsazure"><UpgradeDomain>' . $upgradeDomain . '</UpgradeDomain></WalkUpgradeDomain>');    
1741 
1742       if (!$response->isSuccessful()) {
1743       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1744       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1745     }
1746     }
1747     
1748     /**
1749      * The Reboot Role Instance operation requests a reboot of a role instance
1750      * that is running in a deployment.
1751      * 
1752      * @param string $serviceName   The service name
1753      * @param string $deploymentSlot  The deployment slot (production or staging)
1754      * @param string $roleInstanceName  The role instance name
1755      * @throws Zend_Service_WindowsAzure_Management_Exception
1756      */
1757     public function rebootRoleInstanceBySlot($serviceName, $deploymentSlot, $roleInstanceName)
1758     {
1759         if ($serviceName == '' || is_null($serviceName)) {
1760       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1761         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1762       }
1763       $deploymentSlot = strtolower($deploymentSlot);
1764       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1765       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1766         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1767       }
1768         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
1769       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1770         throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
1771       }
1772       
1773       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot . '/roleinstances/' . $roleInstanceName;
1774       return $this->_rebootOrReimageRoleInstance($operationUrl, 'reboot');
1775     }
1776     
1777     /**
1778      * The Reboot Role Instance operation requests a reboot of a role instance
1779      * that is running in a deployment.
1780      * 
1781      * @param string $serviceName   The service name
1782      * @param string $deploymentId  The deployment ID as listed on the Windows Azure management portal
1783      * @param string $roleInstanceName  The role instance name
1784      * @throws Zend_Service_WindowsAzure_Management_Exception
1785      */
1786     public function rebootRoleInstanceByDeploymentId($serviceName, $deploymentId, $roleInstanceName)
1787     {
1788         if ($serviceName == '' || is_null($serviceName)) {
1789       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1790         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1791       }
1792       if ($deploymentId == '' || is_null($deploymentId)) {
1793       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1794         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1795       }
1796         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
1797       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1798         throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
1799       }
1800       
1801       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId . '/roleinstances/' . $roleInstanceName;
1802       return $this->_rebootOrReimageRoleInstance($operationUrl, 'reboot');
1803     }
1804 
1805     /**
1806      * The Reimage Role Instance operation requests a reimage of a role instance
1807      * that is running in a deployment.
1808      * 
1809      * @param string $serviceName   The service name
1810      * @param string $deploymentSlot  The deployment slot (production or staging)
1811      * @param string $roleInstanceName  The role instance name
1812      * @throws Zend_Service_WindowsAzure_Management_Exception
1813      */
1814     public function reimageRoleInstanceBySlot($serviceName, $deploymentSlot, $roleInstanceName)
1815     {
1816         if ($serviceName == '' || is_null($serviceName)) {
1817       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1818         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1819       }
1820       $deploymentSlot = strtolower($deploymentSlot);
1821       if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
1822       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1823         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
1824       }
1825         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
1826       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1827         throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
1828       }
1829       
1830       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot . '/roleinstances/' . $roleInstanceName;
1831       return $this->_rebootOrReimageRoleInstance($operationUrl, 'reimage');
1832     }
1833     
1834     /**
1835      * The Reimage Role Instance operation requests a reimage of a role instance
1836      * that is running in a deployment.
1837      * 
1838      * @param string $serviceName   The service name
1839      * @param string $deploymentId      The deployment ID as listed on the Windows Azure management portal
1840      * @param string $roleInstanceName  The role instance name
1841      * @throws Zend_Service_WindowsAzure_Management_Exception
1842      */
1843     public function reimageRoleInstanceByDeploymentId($serviceName, $deploymentId, $roleInstanceName)
1844     {
1845         if ($serviceName == '' || is_null($serviceName)) {
1846       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1847         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1848       }
1849       if ($deploymentId == '' || is_null($deploymentId)) {
1850       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1851         throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
1852       }
1853         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
1854       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1855         throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
1856       }
1857       
1858       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId . '/roleinstances/' . $roleInstanceName;
1859       return $this->_rebootOrReimageRoleInstance($operationUrl, 'reimage');
1860     }
1861     
1862     /**
1863      * Reboots or reimages a role instance.
1864      * 
1865      * @param string $operationUrl    The operation url
1866      * @param string $operation The operation (reboot|reimage)
1867      * @throws Zend_Service_WindowsAzure_Management_Exception
1868      */
1869     protected function _rebootOrReimageRoleInstance($operationUrl, $operation = 'reboot')
1870     {
1871         $response = $this->_performRequest($operationUrl, '?comp=' . $operation, Zend_Http_Client::POST);
1872         
1873       if (!$response->isSuccessful()) {
1874       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1875       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1876     }
1877     }
1878     
1879     /**
1880      * The List Certificates operation lists all certificates associated with
1881      * the specified hosted service.
1882      * 
1883      * @param string $serviceName   The service name
1884      * @return array Array of Zend_Service_WindowsAzure_Management_CertificateInstance
1885      * @throws Zend_Service_WindowsAzure_Management_Exception
1886      */
1887     public function listCertificates($serviceName)
1888     {
1889         if ($serviceName == '' || is_null($serviceName)) {
1890       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1891         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1892       }
1893       
1894       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates';
1895         $response = $this->_performRequest($operationUrl);
1896 
1897       if ($response->isSuccessful()) {
1898       $result = $this->_parseResponse($response);
1899 
1900       if (!$result->Certificate) {
1901         return array();
1902       }
1903         if (count($result->Certificate) > 1) {
1904             $xmlServices = $result->Certificate;
1905         } else {
1906             $xmlServices = array($result->Certificate);
1907         }
1908 
1909       $services = array();
1910       if (!is_null($xmlServices)) {       
1911         
1912         for ($i = 0; $i < count($xmlServices); $i++) {
1913           $services[] = new Zend_Service_WindowsAzure_Management_CertificateInstance(
1914               (string)$xmlServices[$i]->CertificateUrl,
1915               (string)$xmlServices[$i]->Thumbprint,
1916               (string)$xmlServices[$i]->ThumbprintAlgorithm,
1917               (string)$xmlServices[$i]->Data
1918           );
1919         }
1920       }
1921       return $services;
1922     } else {
1923       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1924       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1925     }
1926     }
1927     
1928     /**
1929      * The Get Certificate operation returns the public data for the specified certificate.
1930      * 
1931      * @param string $serviceName|$certificateUrl The service name -or- the certificate URL
1932      * @param string $algorithm               Algorithm
1933      * @param string $thumbprint              Thumbprint
1934      * @return Zend_Service_WindowsAzure_Management_CertificateInstance
1935      * @throws Zend_Service_WindowsAzure_Management_Exception
1936      */
1937     public function getCertificate($serviceName, $algorithm = '', $thumbprint = '')
1938     {
1939         if ($serviceName == '' || is_null($serviceName)) {
1940       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1941         throw new Zend_Service_WindowsAzure_Management_Exception('Service name or certificate URL should be specified.');
1942       }
1943       if (strpos($serviceName, 'https') === false && ($algorithm == '' || is_null($algorithm)) && ($thumbprint == '' || is_null($thumbprint))) {
1944       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1945         throw new Zend_Service_WindowsAzure_Management_Exception('Algorithm and thumbprint should be specified.');
1946       }
1947       
1948       $operationUrl = str_replace($this->getBaseUrl(), '', $serviceName);
1949       if (strpos($serviceName, 'https') === false) {
1950         $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates/' . $algorithm . '-' . strtoupper($thumbprint);
1951       }
1952       
1953         $response = $this->_performRequest($operationUrl);
1954 
1955       if ($response->isSuccessful()) {
1956       $result = $this->_parseResponse($response);
1957       
1958       return new Zend_Service_WindowsAzure_Management_CertificateInstance(
1959         $this->getBaseUrl() . $operationUrl,
1960         $algorithm,
1961         $thumbprint,
1962         (string)$result->Data
1963       );
1964     } else {
1965       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1966       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
1967     }
1968     }
1969     
1970     /**
1971      * The Add Certificate operation adds a certificate to the subscription.
1972      * 
1973      * @param string $serviceName         The service name
1974      * @param string $certificateData     Certificate data
1975      * @param string $certificatePassword The certificate password
1976      * @param string $certificateFormat   The certificate format. Currently, only 'pfx' is supported.
1977      * @throws Zend_Service_WindowsAzure_Management_Exception
1978      */
1979     public function addCertificate($serviceName, $certificateData, $certificatePassword, $certificateFormat = 'pfx')
1980     {
1981       if ($serviceName == '' || is_null($serviceName)) {
1982       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1983         throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
1984       }
1985       if ($certificateData == '' || is_null($certificateData)) {
1986       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1987         throw new Zend_Service_WindowsAzure_Management_Exception('Certificate data should be specified.');
1988       }
1989       if ($certificatePassword == '' || is_null($certificatePassword)) {
1990       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1991         throw new Zend_Service_WindowsAzure_Management_Exception('Certificate password should be specified.');
1992       }
1993       if ($certificateFormat != 'pfx') {
1994       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
1995         throw new Zend_Service_WindowsAzure_Management_Exception('Certificate format should be "pfx".');
1996       }
1997       
1998       if (@file_exists($certificateData)) {
1999         $certificateData = file_get_contents($certificateData);
2000       }
2001       
2002       $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates';
2003         $response = $this->_performRequest($operationUrl, '',
2004         Zend_Http_Client::POST,
2005         array('Content-Type' => 'application/xml; charset=utf-8'),
2006         '<CertificateFile xmlns="http://schemas.microsoft.com/windowsazure"><Data>' . base64_encode($certificateData) . '</Data><CertificateFormat>' . $certificateFormat . '</CertificateFormat><Password>' . $certificatePassword . '</Password></CertificateFile>');
2007 
2008       if (!$response->isSuccessful()) {
2009       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2010       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2011     }
2012     }
2013     
2014     /**
2015      * The Delete Certificate operation deletes a certificate from the subscription's certificate store.
2016      * 
2017      * @param string $serviceName|$certificateUrl The service name -or- the certificate URL
2018      * @param string $algorithm               Algorithm
2019      * @param string $thumbprint              Thumbprint
2020      * @throws Zend_Service_WindowsAzure_Management_Exception
2021      */
2022     public function deleteCertificate($serviceName, $algorithm = '', $thumbprint = '')
2023     {
2024         if ($serviceName == '' || is_null($serviceName)) {
2025       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2026         throw new Zend_Service_WindowsAzure_Management_Exception('Service name or certificate URL should be specified.');
2027       }
2028       if (strpos($serviceName, 'https') === false && ($algorithm == '' || is_null($algorithm)) && ($thumbprint == '' || is_null($thumbprint))) {
2029       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2030         throw new Zend_Service_WindowsAzure_Management_Exception('Algorithm and thumbprint should be specified.');
2031       }
2032       
2033       $operationUrl = str_replace($this->getBaseUrl(), '', $serviceName);
2034       if (strpos($serviceName, 'https') === false) {
2035         $operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates/' . $algorithm . '-' . strtoupper($thumbprint);
2036       }
2037       
2038         $response = $this->_performRequest($operationUrl, '', Zend_Http_Client::DELETE);
2039 
2040       if (!$response->isSuccessful()) {
2041       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2042       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2043     }
2044     }
2045     
2046     /**
2047      * The List Affinity Groups operation lists the affinity groups associated with
2048      * the specified subscription.
2049      * 
2050      * @return array Array of Zend_Service_WindowsAzure_Management_AffinityGroupInstance
2051      * @throws Zend_Service_WindowsAzure_Management_Exception
2052      */
2053     public function listAffinityGroups()
2054     {
2055         $response = $this->_performRequest(self::OP_AFFINITYGROUPS);
2056 
2057       if ($response->isSuccessful()) {
2058       $result = $this->_parseResponse($response);
2059       
2060         if (!$result->AffinityGroup) {
2061         return array();
2062       }
2063         if (count($result->AffinityGroup) > 1) {
2064             $xmlServices = $result->AffinityGroup;
2065         } else {
2066             $xmlServices = array($result->AffinityGroup);
2067         }
2068         
2069       $services = array();
2070       if (!is_null($xmlServices)) {       
2071         
2072         for ($i = 0; $i < count($xmlServices); $i++) {
2073           $services[] = new Zend_Service_WindowsAzure_Management_AffinityGroupInstance(
2074               (string)$xmlServices[$i]->Name,
2075               (string)$xmlServices[$i]->Label,
2076               (string)$xmlServices[$i]->Description,
2077               (string)$xmlServices[$i]->Location
2078           );
2079         }
2080       }
2081       return $services;
2082     } else {
2083       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2084       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2085     }
2086     }
2087     
2088     /**
2089      * The Create Affinity Group operation creates a new affinity group for the specified subscription.
2090      * 
2091      * @param string $name A name for the affinity group that is unique to the subscription.
2092      * @param string $label A label for the affinity group. The label may be up to 100 characters in length.
2093      * @param string $description A description for the affinity group. The description may be up to 1024 characters in length.
2094      * @param string $location The location where the affinity group will be created. To list available locations, use the List Locations operation. 
2095      */
2096     public function createAffinityGroup($name, $label, $description = '', $location = '')
2097     {
2098       if ($name == '' || is_null($name)) {
2099       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2100         throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
2101       }
2102       if ($label == '' || is_null($label)) {
2103       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2104         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
2105       }
2106         if (strlen($label) > 100) {
2107       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2108         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
2109       }
2110         if (strlen($description) > 1024) {
2111       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2112         throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.');
2113       }
2114       if ($location == '' || is_null($location)) {
2115       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2116         throw new Zend_Service_WindowsAzure_Management_Exception('Location should be specified.');
2117       }
2118       
2119         $response = $this->_performRequest(self::OP_AFFINITYGROUPS, '',
2120         Zend_Http_Client::POST,
2121         array('Content-Type' => 'application/xml; charset=utf-8'),
2122         '<CreateAffinityGroup xmlns="http://schemas.microsoft.com/windowsazure"><Name>' . $name . '</Name><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description><Location>' . $location . '</Location></CreateAffinityGroup>');  
2123         
2124       if (!$response->isSuccessful()) {
2125       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2126       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2127     }
2128     }
2129     
2130     /**
2131      * The Update Affinity Group operation updates the label and/or the description for an affinity group for the specified subscription.
2132      * 
2133      * @param string $name The name for the affinity group that should be updated.
2134      * @param string $label A label for the affinity group. The label may be up to 100 characters in length.
2135      * @param string $description A description for the affinity group. The description may be up to 1024 characters in length. 
2136      */
2137     public function updateAffinityGroup($name, $label, $description = '')
2138     {
2139       if ($name == '' || is_null($name)) {
2140       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2141         throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
2142       }
2143       if ($label == '' || is_null($label)) {
2144       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2145         throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
2146       }
2147         if (strlen($label) > 100) {
2148       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2149         throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
2150       }
2151         if (strlen($description) > 1024) {
2152       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2153         throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.');
2154       }
2155       
2156         $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $name, '',
2157         Zend_Http_Client::PUT,
2158         array('Content-Type' => 'application/xml; charset=utf-8'),
2159         '<UpdateAffinityGroup xmlns="http://schemas.microsoft.com/windowsazure"><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description></UpdateAffinityGroup>');  
2160         
2161       if (!$response->isSuccessful()) {
2162       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2163       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2164     }
2165     }
2166     
2167     /**
2168      * The Delete Affinity Group operation deletes an affinity group in the specified subscription.
2169      * 
2170      * @param string $name The name for the affinity group that should be deleted.
2171      */
2172     public function deleteAffinityGroup($name)
2173     {
2174       if ($name == '' || is_null($name)) {
2175       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2176         throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
2177       }
2178       
2179         $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $name, '',
2180         Zend_Http_Client::DELETE);
2181         
2182       if (!$response->isSuccessful()) {
2183       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2184       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2185     }
2186     }
2187     
2188     /**
2189      * The Get Affinity Group Properties operation returns the
2190      * system properties associated with the specified affinity group.
2191      * 
2192      * @param string $affinityGroupName The affinity group name.
2193      * @return Zend_Service_WindowsAzure_Management_AffinityGroupInstance
2194      * @throws Zend_Service_WindowsAzure_Management_Exception
2195      */
2196     public function getAffinityGroupProperties($affinityGroupName)
2197     {
2198         if ($affinityGroupName == '' || is_null($affinityGroupName)) {
2199       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2200         throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
2201       }
2202       
2203         $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $affinityGroupName);
2204 
2205       if ($response->isSuccessful()) {
2206       $result = $this->_parseResponse($response);
2207       
2208       $affinityGroup = new Zend_Service_WindowsAzure_Management_AffinityGroupInstance(
2209         $affinityGroupName,
2210         (string)$result->Label,
2211         (string)$result->Description,
2212         (string)$result->Location
2213       );
2214 
2215       // Hosted services
2216       if (count($result->HostedServices->HostedService) > 1) {
2217           $xmlService = $result->HostedServices->HostedService;
2218         } else {
2219           $xmlService = array($result->HostedServices->HostedService);
2220         }
2221             
2222       $services = array();
2223       if (!is_null($xmlService)) {        
2224         for ($i = 0; $i < count($xmlService); $i++) {
2225           $services[] = array(
2226             'url' => (string)$xmlService[$i]->Url,
2227             'name' => (string)$xmlService[$i]->ServiceName
2228           );
2229         }
2230       }
2231       $affinityGroup->HostedServices = $services;
2232       
2233       // Storage services
2234       if (count($result->StorageServices->StorageService) > 1) {
2235           $xmlService = $result->StorageServices->StorageService;
2236         } else {
2237           $xmlService = array($result->StorageServices->StorageService);
2238         }
2239             
2240       $services = array();
2241       if (!is_null($xmlService)) {        
2242         for ($i = 0; $i < count($xmlService); $i++) {
2243           $services[] = array(
2244             'url' => (string)$xmlService[$i]->Url,
2245             'name' => (string)$xmlService[$i]->ServiceName
2246           );
2247         }
2248       }
2249       $affinityGroup->StorageServices = $services;  
2250       
2251       return $affinityGroup;
2252     } else {
2253       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2254       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2255     }
2256     }
2257     
2258     /**
2259      * The List Locations operation lists all of the data center locations
2260      * that are valid for your subscription.
2261      * 
2262      * @return array Array of Zend_Service_WindowsAzure_Management_LocationInstance
2263      * @throws Zend_Service_WindowsAzure_Management_Exception
2264      */
2265     public function listLocations()
2266     {
2267         $response = $this->_performRequest(self::OP_LOCATIONS);
2268 
2269       if ($response->isSuccessful()) {
2270       $result = $this->_parseResponse($response);
2271       
2272         if (!$result->Location) {
2273         return array();
2274       }
2275         if (count($result->Location) > 1) {
2276             $xmlServices = $result->Location;
2277         } else {
2278             $xmlServices = array($result->Location);
2279         }
2280         
2281       $services = array();
2282       if (!is_null($xmlServices)) {       
2283         
2284         for ($i = 0; $i < count($xmlServices); $i++) {
2285           $services[] = new Zend_Service_WindowsAzure_Management_LocationInstance(
2286               (string)$xmlServices[$i]->Name
2287           );
2288         }
2289       }
2290       return $services;
2291     } else {
2292       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2293       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2294     }
2295     }
2296     
2297     /**
2298      * The List Operating Systems operation lists the versions of the guest operating system
2299      * that are currently available in Windows Azure. The 2010-10-28 version of List Operating
2300      * Systems also indicates what family an operating system version belongs to.
2301      * Currently Windows Azure supports two operating system families: the Windows Azure guest
2302      * operating system that is substantially compatible with Windows Server 2008 SP2,
2303      * and the Windows Azure guest operating system that is substantially compatible with
2304      * Windows Server 2008 R2.
2305      * 
2306      * @return array Array of Zend_Service_WindowsAzure_Management_OperatingSystemInstance
2307      * @throws Zend_Service_WindowsAzure_Management_Exception
2308      */
2309     public function listOperatingSystems()
2310     {
2311         $response = $this->_performRequest(self::OP_OPERATINGSYSTEMS);
2312 
2313       if ($response->isSuccessful()) {
2314       $result = $this->_parseResponse($response);
2315       
2316         if (!$result->OperatingSystem) {
2317         return array();
2318       }
2319         if (count($result->OperatingSystem) > 1) {
2320             $xmlServices = $result->OperatingSystem;
2321         } else {
2322             $xmlServices = array($result->OperatingSystem);
2323         }
2324         
2325       $services = array();
2326       if (!is_null($xmlServices)) {       
2327         
2328         for ($i = 0; $i < count($xmlServices); $i++) {
2329           $services[] = new Zend_Service_WindowsAzure_Management_OperatingSystemInstance(
2330               (string)$xmlServices[$i]->Version,
2331               (string)$xmlServices[$i]->Label,
2332               ((string)$xmlServices[$i]->IsDefault == 'true'),
2333               ((string)$xmlServices[$i]->IsActive == 'true'),
2334               (string)$xmlServices[$i]->Family,
2335               (string)$xmlServices[$i]->FamilyLabel
2336           );
2337         }
2338       }
2339       return $services;
2340     } else {
2341       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2342       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2343     }
2344     }
2345     
2346     /**
2347      * The List OS Families operation lists the guest operating system families
2348      * available in Windows Azure, and also lists the operating system versions
2349      * available for each family. Currently Windows Azure supports two operating
2350      * system families: the Windows Azure guest operating system that is
2351      * substantially compatible with Windows Server 2008 SP2, and the Windows
2352      * Azure guest operating system that is substantially compatible with
2353      * Windows Server 2008 R2.
2354      * 
2355      * @return array Array of Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance
2356      * @throws Zend_Service_WindowsAzure_Management_Exception
2357      */
2358     public function listOperatingSystemFamilies()
2359     {
2360         $response = $this->_performRequest(self::OP_OPERATINGSYSTEMFAMILIES);
2361 
2362       if ($response->isSuccessful()) {
2363       $result = $this->_parseResponse($response);
2364       
2365         if (!$result->OperatingSystemFamily) {
2366         return array();
2367       }
2368         if (count($result->OperatingSystemFamily) > 1) {
2369             $xmlServices = $result->OperatingSystemFamily;
2370         } else {
2371             $xmlServices = array($result->OperatingSystemFamily);
2372         }
2373         
2374       $services = array();
2375       if (!is_null($xmlServices)) {       
2376         
2377         for ($i = 0; $i < count($xmlServices); $i++) {
2378           $services[] = new Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance(
2379               (string)$xmlServices[$i]->Name,
2380               (string)$xmlServices[$i]->Label
2381           );
2382                 
2383           if (count($xmlServices[$i]->OperatingSystems->OperatingSystem) > 1) {
2384                 $xmlOperatingSystems = $xmlServices[$i]->OperatingSystems->OperatingSystem;
2385             } else {
2386                 $xmlOperatingSystems = array($xmlServices[$i]->OperatingSystems->OperatingSystem);
2387             }
2388             
2389           $operatingSystems = array();
2390           if (!is_null($xmlOperatingSystems)) {       
2391             // require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php';
2392             for ($i = 0; $i < count($xmlOperatingSystems); $i++) {
2393               $operatingSystems[] = new Zend_Service_WindowsAzure_Management_OperatingSystemInstance(
2394                   (string)$xmlOperatingSystems[$i]->Version,
2395                   (string)$xmlOperatingSystems[$i]->Label,
2396                   ((string)$xmlOperatingSystems[$i]->IsDefault == 'true'),
2397                   ((string)$xmlOperatingSystems[$i]->IsActive == 'true'),
2398                   (string)$xmlServices[$i]->Name,
2399                   (string)$xmlServices[$i]->Label
2400               );
2401             }
2402           }
2403           $services[ count($services) - 1 ]->OperatingSystems = $operatingSystems;
2404         }
2405       }
2406       return $services;
2407     } else {
2408       // require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
2409       throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
2410     }
2411     }
2412     
2413     /**
2414      * Clean configuration
2415      * 
2416      * @param string $configuration Configuration to clean.
2417      * @return string
2418      */
2419     public function _cleanConfiguration($configuration) {
2420       $configuration = str_replace('?<?', '<?', $configuration);
2421     $configuration = str_replace("\r", "", $configuration);
2422     $configuration = str_replace("\n", "", $configuration);
2423     
2424     return $configuration;
2425     }
2426 }