web/lib/Zend/Service/WindowsAzure/Management/Client.php
changeset 808 6b6c2214f778
child 1230 68c69c656a2c
equal deleted inserted replaced
807:877f952ae2bd 808:6b6c2214f778
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Service_WindowsAzure
       
    17  * @subpackage Management
       
    18  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id$
       
    21  */
       
    22 
       
    23 /**
       
    24  * @see Zend_Service_WindowsAzure_Management_OperationStatusInstance
       
    25  */
       
    26 require_once 'Zend/Service/WindowsAzure/Management/OperationStatusInstance.php';
       
    27 
       
    28 /**
       
    29  * @see Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance
       
    30  */
       
    31 require_once 'Zend/Service/WindowsAzure/Management/SubscriptionOperationInstance.php';
       
    32 
       
    33 /**
       
    34  * @see Zend_Service_WindowsAzure_Management_DeploymentInstance
       
    35  */
       
    36 require_once 'Zend/Service/WindowsAzure/Management/DeploymentInstance.php';
       
    37 
       
    38 /**
       
    39  * @see Zend_Service_WindowsAzure_Storage_Blob
       
    40  */
       
    41 require_once 'Zend/Service/WindowsAzure/Storage/Blob.php';
       
    42 
       
    43 /**
       
    44  * @see Zend_Service_WindowsAzure_Storage_Table
       
    45  */
       
    46 require_once 'Zend/Service/WindowsAzure/Storage/Table.php';
       
    47 
       
    48 /**
       
    49  * @see Zend_Service_WindowsAzure_Management_HostedServiceInstance
       
    50  */
       
    51 require_once 'Zend/Service/WindowsAzure/Management/HostedServiceInstance.php';
       
    52 
       
    53 /**
       
    54  * @see Zend_Service_WindowsAzure_Management_CertificateInstance
       
    55  */
       
    56 require_once 'Zend/Service/WindowsAzure/Management/CertificateInstance.php';
       
    57 
       
    58 /**
       
    59  * @see Zend_Service_WindowsAzure_Management_AffinityGroupInstance
       
    60  */
       
    61 require_once 'Zend/Service/WindowsAzure/Management/AffinityGroupInstance.php';
       
    62 
       
    63 /**
       
    64  * @see Zend_Service_WindowsAzure_Management_LocationInstance
       
    65  */
       
    66 require_once 'Zend/Service/WindowsAzure/Management/LocationInstance.php';
       
    67 
       
    68 /**
       
    69  * @see Zend_Service_WindowsAzure_Management_OperatingSystemInstance
       
    70  */
       
    71 require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php';
       
    72 
       
    73 /**
       
    74  * @see Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance
       
    75  */
       
    76 require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemFamilyInstance.php';
       
    77 
       
    78 /**
       
    79  * @category   Zend
       
    80  * @package    Zend_Service_WindowsAzure
       
    81  * @subpackage Management
       
    82  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
    83  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    84  */
       
    85 class Zend_Service_WindowsAzure_Management_Client
       
    86 {
       
    87 	/**
       
    88 	 * Management service URL
       
    89 	 */
       
    90 	const URL_MANAGEMENT        = "https://management.core.windows.net";
       
    91 	
       
    92 	/**
       
    93 	 * Operations
       
    94 	 */
       
    95 	const OP_OPERATIONS                = "operations";
       
    96 	const OP_STORAGE_ACCOUNTS          = "services/storageservices";
       
    97 	const OP_HOSTED_SERVICES           = "services/hostedservices";
       
    98 	const OP_AFFINITYGROUPS            = "affinitygroups";
       
    99 	const OP_LOCATIONS                 = "locations";
       
   100 	const OP_OPERATINGSYSTEMS          = "operatingsystems";
       
   101 	const OP_OPERATINGSYSTEMFAMILIES   = "operatingsystemfamilies";
       
   102 
       
   103 	/**
       
   104 	 * Current API version
       
   105 	 * 
       
   106 	 * @var string
       
   107 	 */
       
   108 	protected $_apiVersion = '2011-02-25';
       
   109 	
       
   110 	/**
       
   111 	 * Subscription ID
       
   112 	 *
       
   113 	 * @var string
       
   114 	 */
       
   115 	protected $_subscriptionId = '';
       
   116 	
       
   117 	/**
       
   118 	 * Management certificate path (.PEM)
       
   119 	 *
       
   120 	 * @var string
       
   121 	 */
       
   122 	protected $_certificatePath = '';
       
   123 	
       
   124 	/**
       
   125 	 * Management certificate passphrase
       
   126 	 *
       
   127 	 * @var string
       
   128 	 */
       
   129 	protected $_certificatePassphrase = '';
       
   130 	
       
   131 	/**
       
   132 	 * Zend_Http_Client channel used for communication with REST services
       
   133 	 * 
       
   134 	 * @var Zend_Http_Client
       
   135 	 */
       
   136 	protected $_httpClientChannel = null;	
       
   137 
       
   138 	/**
       
   139 	 * Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract instance
       
   140 	 * 
       
   141 	 * @var Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
       
   142 	 */
       
   143 	protected $_retryPolicy = null;
       
   144 	
       
   145 	/**
       
   146 	 * Returns the last request ID
       
   147 	 * 
       
   148 	 * @var string
       
   149 	 */
       
   150 	protected $_lastRequestId = null;
       
   151 	
       
   152 	/**
       
   153 	 * Creates a new Zend_Service_WindowsAzure_Management instance
       
   154 	 * 
       
   155 	 * @param string $subscriptionId Subscription ID
       
   156 	 * @param string $certificatePath Management certificate path (.PEM)
       
   157 	 * @param string $certificatePassphrase Management certificate passphrase
       
   158      * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
       
   159 	 */
       
   160 	public function __construct(
       
   161 		$subscriptionId,
       
   162 		$certificatePath,
       
   163 		$certificatePassphrase,
       
   164 		Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null
       
   165 	) {
       
   166 		$this->_subscriptionId = $subscriptionId;
       
   167 		$this->_certificatePath = $certificatePath;
       
   168 		$this->_certificatePassphrase = $certificatePassphrase;
       
   169 		
       
   170 		$this->_retryPolicy = $retryPolicy;
       
   171 		if (is_null($this->_retryPolicy)) {
       
   172 		    $this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
       
   173 		}
       
   174 		
       
   175 		// Setup default Zend_Http_Client channel
       
   176 		$options = array(
       
   177 		    'adapter'       => 'Zend_Http_Client_Adapter_Socket',
       
   178 		    'ssltransport'  => 'ssl',
       
   179 			'sslcert'       => $this->_certificatePath,
       
   180 			'sslpassphrase' => $this->_certificatePassphrase,
       
   181 			'sslusecontext' => true,
       
   182 		);
       
   183 		if (function_exists('curl_init')) {
       
   184 			// Set cURL options if cURL is used afterwards
       
   185 			$options['curloptions'] = array(
       
   186 					CURLOPT_FOLLOWLOCATION => true,
       
   187 					CURLOPT_TIMEOUT => 120,
       
   188 			);
       
   189 		}
       
   190 		$this->_httpClientChannel = new Zend_Http_Client(null, $options);
       
   191 	}
       
   192 	
       
   193 	/**
       
   194 	 * Set the HTTP client channel to use
       
   195 	 * 
       
   196 	 * @param Zend_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name.
       
   197 	 */
       
   198 	public function setHttpClientChannel($adapterInstance = 'Zend_Http_Client_Adapter_Socket')
       
   199 	{
       
   200 		$this->_httpClientChannel->setAdapter($adapterInstance);
       
   201 	}
       
   202 	
       
   203     /**
       
   204      * Retrieve HTTP client channel
       
   205      * 
       
   206      * @return Zend_Http_Client_Adapter_Interface
       
   207      */
       
   208     public function getHttpClientChannel()
       
   209     {
       
   210         return $this->_httpClientChannel;
       
   211     }
       
   212 	
       
   213 	/**
       
   214 	 * Returns the Windows Azure subscription ID
       
   215 	 * 
       
   216 	 * @return string
       
   217 	 */
       
   218 	public function getSubscriptionId()
       
   219 	{
       
   220 		return $this->_subscriptionId;
       
   221 	}
       
   222 	
       
   223 	/**
       
   224 	 * Returns the last request ID.
       
   225 	 * 
       
   226 	 * @return string
       
   227 	 */
       
   228 	public function getLastRequestId()
       
   229 	{
       
   230 		return $this->_lastRequestId;
       
   231 	}
       
   232 	
       
   233 	/**
       
   234 	 * Get base URL for creating requests
       
   235 	 *
       
   236 	 * @return string
       
   237 	 */
       
   238 	public function getBaseUrl()
       
   239 	{
       
   240 		return self::URL_MANAGEMENT . '/' . $this->_subscriptionId;
       
   241 	}
       
   242 	
       
   243 	/**
       
   244 	 * Perform request using Zend_Http_Client channel
       
   245 	 *
       
   246 	 * @param string $path Path
       
   247 	 * @param string $queryString Query string
       
   248 	 * @param string $httpVerb HTTP verb the request will use
       
   249 	 * @param array $headers x-ms headers to add
       
   250 	 * @param mixed $rawData Optional RAW HTTP data to be sent over the wire
       
   251 	 * @return Zend_Http_Response
       
   252 	 */
       
   253 	protected function _performRequest(
       
   254 		$path = '/',
       
   255 		$queryString = '',
       
   256 		$httpVerb = Zend_Http_Client::GET,
       
   257 		$headers = array(),
       
   258 		$rawData = null
       
   259 	) {
       
   260 	    // Clean path
       
   261 		if (strpos($path, '/') !== 0) {
       
   262 			$path = '/' . $path;
       
   263 		}
       
   264 			
       
   265 		// Clean headers
       
   266 		if (is_null($headers)) {
       
   267 		    $headers = array();
       
   268 		}
       
   269 		
       
   270 		// Ensure cUrl will also work correctly:
       
   271 		//  - disable Content-Type if required
       
   272 		//  - disable Expect: 100 Continue
       
   273 		if (!isset($headers["Content-Type"])) {
       
   274 			$headers["Content-Type"] = '';
       
   275 		}
       
   276 		//$headers["Expect"] = '';
       
   277 
       
   278 		// Add version header
       
   279 		$headers['x-ms-version'] = $this->_apiVersion;
       
   280 		    
       
   281 		// URL encoding
       
   282 		$path           = self::urlencode($path);
       
   283 		$queryString    = self::urlencode($queryString);
       
   284 
       
   285 		// Generate URL and sign request
       
   286 		$requestUrl     = $this->getBaseUrl() . $path . $queryString;
       
   287 		$requestHeaders = $headers;
       
   288 
       
   289 		// Prepare request 
       
   290 		$this->_httpClientChannel->resetParameters(true);
       
   291 		$this->_httpClientChannel->setUri($requestUrl);
       
   292 		$this->_httpClientChannel->setHeaders($requestHeaders);
       
   293 		$this->_httpClientChannel->setRawData($rawData);
       
   294 
       
   295 		// Execute request
       
   296 		$response = $this->_retryPolicy->execute(
       
   297 		    array($this->_httpClientChannel, 'request'),
       
   298 		    array($httpVerb)
       
   299 		);
       
   300 		
       
   301 		// Store request id
       
   302 		$this->_lastRequestId = $response->getHeader('x-ms-request-id');
       
   303 		
       
   304 		return $response;
       
   305 	}
       
   306 	
       
   307 	/** 
       
   308 	 * Parse result from Zend_Http_Response
       
   309 	 *
       
   310 	 * @param Zend_Http_Response $response Response from HTTP call
       
   311 	 * @return object
       
   312 	 * @throws Zend_Service_WindowsAzure_Exception
       
   313 	 */
       
   314 	protected function _parseResponse(Zend_Http_Response $response = null)
       
   315 	{
       
   316 		if (is_null($response)) {
       
   317 			require_once 'Zend/Service/WindowsAzure/Exception.php';
       
   318 			throw new Zend_Service_WindowsAzure_Exception('Response should not be null.');
       
   319 		}
       
   320 		
       
   321         $xml = @simplexml_load_string($response->getBody());
       
   322         
       
   323         if ($xml !== false) {
       
   324             // Fetch all namespaces 
       
   325             $namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true)); 
       
   326             
       
   327             // Register all namespace prefixes
       
   328             foreach ($namespaces as $prefix => $ns) { 
       
   329                 if ($prefix != '') {
       
   330                     $xml->registerXPathNamespace($prefix, $ns);
       
   331                 } 
       
   332             } 
       
   333         }
       
   334         
       
   335         return $xml;
       
   336 	}
       
   337 	
       
   338 	/**
       
   339 	 * URL encode function
       
   340 	 * 
       
   341 	 * @param  string $value Value to encode
       
   342 	 * @return string        Encoded value
       
   343 	 */
       
   344 	public static function urlencode($value)
       
   345 	{
       
   346 	    return str_replace(' ', '%20', $value);
       
   347 	}
       
   348 	
       
   349     /**
       
   350      * Builds a query string from an array of elements
       
   351      * 
       
   352      * @param array     Array of elements
       
   353      * @return string   Assembled query string
       
   354      */
       
   355     public static function createQueryStringFromArray($queryString)
       
   356     {
       
   357     	return count($queryString) > 0 ? '?' . implode('&', $queryString) : '';
       
   358     }
       
   359     
       
   360 	/**
       
   361 	 * Get error message from Zend_Http_Response
       
   362 	 *
       
   363 	 * @param Zend_Http_Response $response Repsonse
       
   364 	 * @param string $alternativeError Alternative error message
       
   365 	 * @return string
       
   366 	 */
       
   367 	protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.')
       
   368 	{
       
   369 		$response = $this->_parseResponse($response);
       
   370 		if ($response && $response->Message) {
       
   371 			return (string)$response->Message;
       
   372 		} else {
       
   373 			return $alternativeError;
       
   374 		}
       
   375 	}
       
   376     
       
   377     /**
       
   378      * The Get Operation Status operation returns the status of the specified operation.
       
   379      * After calling an asynchronous operation, you can call Get Operation Status to
       
   380      * determine whether the operation has succeed, failed, or is still in progress.
       
   381      *
       
   382      * @param string $requestId The request ID. If omitted, the last request ID will be used.
       
   383      * @return Zend_Service_WindowsAzure_Management_OperationStatusInstance
       
   384      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   385      */
       
   386     public function getOperationStatus($requestId = '')
       
   387     {
       
   388     	if ($requestId == '') {
       
   389     		$requestId = $this->getLastRequestId();
       
   390     	}
       
   391     	
       
   392     	$response = $this->_performRequest(self::OP_OPERATIONS . '/' . $requestId);
       
   393 
       
   394     	if ($response->isSuccessful()) {
       
   395 			$result = $this->_parseResponse($response);
       
   396 
       
   397 			if (!is_null($result)) {
       
   398 				return new Zend_Service_WindowsAzure_Management_OperationStatusInstance(
       
   399 					(string)$result->ID,
       
   400 					(string)$result->Status,
       
   401 					($result->Error ? (string)$result->Error->Code : ''),
       
   402 					($result->Error ? (string)$result->Error->Message : '')
       
   403 				);
       
   404 			}
       
   405 			return null;
       
   406 		} else {
       
   407 			require_once 'Zend/Service/Management/Exception.php';
       
   408 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   409 		}
       
   410     }
       
   411     
       
   412 
       
   413     
       
   414     /**
       
   415      * The List Subscription Operations operation returns a list of create, update,
       
   416      * and delete operations that were performed on a subscription during the specified timeframe.
       
   417      * Documentation on the parameters can be found at http://msdn.microsoft.com/en-us/library/gg715318.aspx.
       
   418      *
       
   419      * @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.
       
   420      * @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. 
       
   421      * @param string $objectIdFilter Returns subscription operations only for the specified object type and object ID. 
       
   422      * @param string $operationResultFilter Returns subscription operations only for the specified result status, either Succeeded, Failed, or InProgress.
       
   423      * @param string $continuationToken Internal usage.
       
   424      * @return array Array of Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance
       
   425      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   426      */
       
   427     public function listSubscriptionOperations($startTime, $endTime, $objectIdFilter = null, $operationResultFilter = null, $continuationToken = null)
       
   428     {
       
   429     	if ($startTime == '' || is_null($startTime)) {
       
   430 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   431     		throw new Zend_Service_WindowsAzure_Management_Exception('Start time should be specified.');
       
   432     	}
       
   433     	if ($endTime == '' || is_null($endTime)) {
       
   434 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   435     		throw new Zend_Service_WindowsAzure_Management_Exception('End time should be specified.');
       
   436     	}
       
   437     	if ($operationResultFilter != '' && !is_null($operationResultFilter)) {
       
   438 	        $operationResultFilter = strtolower($operationResultFilter);
       
   439 	    	if ($operationResultFilter != 'succeeded' && $operationResultFilter != 'failed' && $operationResultFilter != 'inprogress') {
       
   440 				require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   441 	    		throw new Zend_Service_WindowsAzure_Management_Exception('OperationResultFilter should be succeeded|failed|inprogress.');
       
   442 	    	}
       
   443     	}
       
   444     	
       
   445     	$parameters = array();
       
   446     	$parameters[] = 'StartTime=' . $startTime;
       
   447     	$parameters[] = 'EndTime=' . $endTime;
       
   448     	if ($objectIdFilter != '' && !is_null($objectIdFilter)) {
       
   449     		$parameters[] = 'ObjectIdFilter=' . $objectIdFilter;
       
   450     	}
       
   451     	if ($operationResultFilter != '' && !is_null($operationResultFilter)) {
       
   452     		$parameters[] = 'OperationResultFilter=' . ucfirst($operationResultFilter);
       
   453     	}
       
   454     	if ($continuationToken != '' && !is_null($continuationToken)) {
       
   455     		$parameters[] = 'ContinuationToken=' . $continuationToken;
       
   456     	}
       
   457     	
       
   458     	$response = $this->_performRequest(self::OP_OPERATIONS, '?' . implode('&', $parameters));
       
   459 
       
   460     	if ($response->isSuccessful()) {
       
   461 			$result = $this->_parseResponse($response);
       
   462 			$namespaces = $result->getDocNamespaces(); 
       
   463     		$result->registerXPathNamespace('__empty_ns', $namespaces['']);
       
   464  
       
   465 			$xmlOperations = $result->xpath('//__empty_ns:SubscriptionOperation');
       
   466 			
       
   467 		    // Create return value
       
   468 		    $returnValue = array();		    
       
   469 		    foreach ($xmlOperations as $xmlOperation) {
       
   470 		    	// Create operation instance
       
   471 		    	$operation = new Zend_Service_WindowsAzure_Management_SubscriptionOperationInstance(
       
   472 		    		$xmlOperation->OperationId,
       
   473 		    		$xmlOperation->OperationObjectId,
       
   474 		    		$xmlOperation->OperationName,
       
   475 		    		array(),
       
   476 		    		(array)$xmlOperation->OperationCaller,
       
   477 		    		(array)$xmlOperation->OperationStatus
       
   478 		    	);
       
   479 		    	
       
   480 		    	// Parse parameters
       
   481 		    	$xmlOperation->registerXPathNamespace('__empty_ns', $namespaces['']); 
       
   482 		    	$xmlParameters = $xmlOperation->xpath('.//__empty_ns:OperationParameter');
       
   483 		    	foreach ($xmlParameters as $xmlParameter) {
       
   484 		    		$xmlParameterDetails = $xmlParameter->children('http://schemas.datacontract.org/2004/07/Microsoft.Samples.WindowsAzure.ServiceManagement');
       
   485 		    		$operation->addOperationParameter((string)$xmlParameterDetails->Name, (string)$xmlParameterDetails->Value);
       
   486 		    	}
       
   487 		    	
       
   488     		    // Add to result
       
   489     		    $returnValue[] = $operation;
       
   490 		    }
       
   491 		    
       
   492 			// More data?
       
   493 		    if (!is_null($result->ContinuationToken) && $result->ContinuationToken != '') {
       
   494 		    	$returnValue = array_merge($returnValue, $this->listSubscriptionOperations($startTime, $endTime, $objectIdFilter, $operationResultFilter, (string)$result->ContinuationToken));
       
   495 		    }
       
   496 		    
       
   497 		    // Return
       
   498 		    return $returnValue;
       
   499 		} else {
       
   500 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   501 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   502 		}
       
   503     }
       
   504     
       
   505     /**
       
   506      * Wait for an operation to complete
       
   507      * 
       
   508      * @param string $requestId The request ID. If omitted, the last request ID will be used.
       
   509      * @param int $sleepInterval Sleep interval in milliseconds.
       
   510      * @return Zend_Service_WindowsAzure_Management_OperationStatusInstance
       
   511      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   512      */
       
   513     public function waitForOperation($requestId = '', $sleepInterval = 250)
       
   514     {
       
   515     	if ($requestId == '') {
       
   516     		$requestId = $this->getLastRequestId();
       
   517     	}
       
   518     	if ($requestId == '' || is_null($requestId)) {
       
   519     		return null;
       
   520     	}
       
   521 
       
   522 		$status = $this->getOperationStatus($requestId);
       
   523 		while ($status->Status == 'InProgress') {
       
   524 		  $status = $this->getOperationStatus($requestId);
       
   525 		  usleep($sleepInterval);
       
   526 		}
       
   527 		
       
   528 		return $status;
       
   529     }
       
   530     
       
   531 	/**
       
   532 	 * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance for the current account
       
   533 	 *
       
   534 	 * @param string $serviceName the service name to create a storage client for.
       
   535 	 * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
       
   536 	 * @return Zend_Service_WindowsAzure_Storage_Blob
       
   537 	 */
       
   538 	public function createBlobClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
       
   539 	{
       
   540 		if ($serviceName == '' || is_null($serviceName)) {
       
   541     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   542     	}
       
   543     	
       
   544     	$storageKeys = $this->getStorageAccountKeys($serviceName);
       
   545     	
       
   546 		
       
   547 		
       
   548 		return new Zend_Service_WindowsAzure_Storage_Blob(
       
   549 			Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB,
       
   550 			$serviceName,
       
   551 			$storageKeys[0],
       
   552 			false,
       
   553 			$retryPolicy
       
   554 		);
       
   555 	}
       
   556 	
       
   557 	/**
       
   558 	 * Creates a new Zend_Service_WindowsAzure_Storage_Table instance for the current account
       
   559 	 *
       
   560 	 * @param string $serviceName the service name to create a storage client for.
       
   561 	 * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
       
   562 	 * @return Zend_Service_WindowsAzure_Storage_Table
       
   563 	 */
       
   564 	public function createTableClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
       
   565 	{
       
   566 		if ($serviceName == '' || is_null($serviceName)) {
       
   567 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   568     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   569     	}
       
   570     	
       
   571     	$storageKeys = $this->getStorageAccountKeys($serviceName);
       
   572 		
       
   573 		return new Zend_Service_WindowsAzure_Storage_Table(
       
   574 			Zend_Service_WindowsAzure_Storage::URL_CLOUD_TABLE,
       
   575 			$serviceName,
       
   576 			$storageKeys[0],
       
   577 			false,
       
   578 			$retryPolicy
       
   579 		);
       
   580 	}
       
   581 	
       
   582 	/**
       
   583 	 * Creates a new Zend_Service_WindowsAzure_Storage_Queue instance for the current account
       
   584 	 *
       
   585 	 * @param string $serviceName the service name to create a storage client for.
       
   586 	 * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
       
   587 	 * @return Zend_Service_WindowsAzure_Storage_Queue
       
   588 	 */
       
   589 	public function createQueueClientForService($serviceName, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
       
   590 	{
       
   591 		if ($serviceName == '' || is_null($serviceName)) {
       
   592 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   593     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   594     	}
       
   595     	
       
   596     	$storageKeys = $this->getStorageAccountKeys($serviceName);
       
   597     	
       
   598 		require_once 'Zend/Service/WindowsAzure/Storage/Queue.php';
       
   599 		
       
   600 		return new Zend_Service_WindowsAzure_Storage_Queue(
       
   601 			Zend_Service_WindowsAzure_Storage::URL_CLOUD_QUEUE,
       
   602 			$serviceName,
       
   603 			$storageKeys[0],
       
   604 			false,
       
   605 			$retryPolicy
       
   606 		);
       
   607 	}
       
   608     
       
   609     /**
       
   610      * The List Storage Accounts operation lists the storage accounts available under
       
   611      * the current subscription.
       
   612      *
       
   613      * @return array An array of Zend_Service_WindowsAzure_Management_StorageServiceInstance
       
   614      */
       
   615     public function listStorageAccounts()
       
   616     {
       
   617     	$response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS);
       
   618 
       
   619     	if ($response->isSuccessful()) {
       
   620 			$result = $this->_parseResponse($response);
       
   621 			
       
   622     		if (!$result->StorageService) {
       
   623 				return array();
       
   624 			}
       
   625 		    if (count($result->StorageService) > 1) {
       
   626     		    $xmlServices = $result->StorageService;
       
   627     		} else {
       
   628     		    $xmlServices = array($result->StorageService);
       
   629     		}
       
   630     		
       
   631 			$services = array();
       
   632 			if (!is_null($xmlServices)) {				
       
   633 				for ($i = 0; $i < count($xmlServices); $i++) {
       
   634 					$services[] = new Zend_Service_WindowsAzure_Management_StorageServiceInstance(
       
   635 					    (string)$xmlServices[$i]->Url,
       
   636 					    (string)$xmlServices[$i]->ServiceName
       
   637 					);
       
   638 				}
       
   639 			}
       
   640 			return $services;
       
   641 		} else {
       
   642 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   643 		}
       
   644     }
       
   645     
       
   646     /**
       
   647      * The Get Storage Account Properties operation returns the system properties for the
       
   648      * specified storage account. These properties include: the address, description, and 
       
   649      * label of the storage account; and the name of the affinity group to which the service
       
   650      * belongs, or its geo-location if it is not part of an affinity group.
       
   651      *
       
   652      * @param string $serviceName The name of your service.
       
   653      * @return Zend_Service_WindowsAzure_Management_StorageServiceInstance
       
   654      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   655      */
       
   656     public function getStorageAccountProperties($serviceName)
       
   657     {
       
   658     	if ($serviceName == '' || is_null($serviceName)) {
       
   659     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   660     	}
       
   661     	
       
   662     	$response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS . '/' . $serviceName);
       
   663 
       
   664     	if ($response->isSuccessful()) {
       
   665 			$xmlService = $this->_parseResponse($response);
       
   666 
       
   667 			if (!is_null($xmlService)) {
       
   668 				require_once 'Zend/Service/WindowsAzure/Management/StorageServiceInstance.php';
       
   669 				
       
   670 				return new Zend_Service_WindowsAzure_Management_StorageServiceInstance(
       
   671 					(string)$xmlService->Url,
       
   672 					(string)$xmlService->ServiceName,
       
   673 					(string)$xmlService->StorageServiceProperties->Description,
       
   674 					(string)$xmlService->StorageServiceProperties->AffinityGroup,
       
   675 					(string)$xmlService->StorageServiceProperties->Location,
       
   676 					(string)$xmlService->StorageServiceProperties->Label
       
   677 				);
       
   678 			}
       
   679 			return null;
       
   680 		} else {
       
   681 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   682 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   683 		}
       
   684     }
       
   685     
       
   686     /**
       
   687      * The Get Storage Keys operation returns the primary
       
   688      * and secondary access keys for the specified storage account.
       
   689      *
       
   690      * @param string $serviceName The name of your service.
       
   691      * @return array An array of strings
       
   692      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   693      */
       
   694     public function getStorageAccountKeys($serviceName)
       
   695     {
       
   696     	if ($serviceName == '' || is_null($serviceName)) {
       
   697 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   698     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   699     	}
       
   700     	
       
   701     	$response = $this->_performRequest(self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys');
       
   702 
       
   703     	if ($response->isSuccessful()) {
       
   704 			$xmlService = $this->_parseResponse($response);
       
   705 
       
   706 			if (!is_null($xmlService)) {
       
   707 				return array(
       
   708 					(string)$xmlService->StorageServiceKeys->Primary,
       
   709 					(string)$xmlService->StorageServiceKeys->Secondary
       
   710 				);
       
   711 			}
       
   712 			return array();
       
   713 		} else {
       
   714 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   715 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   716 		}
       
   717     }
       
   718     
       
   719     /**
       
   720      * The Regenerate Keys operation regenerates the primary
       
   721      * or secondary access key for the specified storage account.
       
   722      *
       
   723      * @param string $serviceName The name of your service.
       
   724      * @param string $key		  The key to regenerate (primary or secondary)
       
   725      * @return array An array of strings
       
   726      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   727      */
       
   728     public function regenerateStorageAccountKey($serviceName, $key = 'primary')
       
   729     {
       
   730     	if ($serviceName == '' || is_null($serviceName)) {
       
   731 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   732     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   733     	}
       
   734     	$key = strtolower($key);
       
   735     	if ($key != 'primary' && $key != 'secondary') {
       
   736 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   737     		throw new Zend_Service_WindowsAzure_Management_Exception('Key identifier should be primary|secondary.');
       
   738     	}
       
   739     	
       
   740     	$response = $this->_performRequest(
       
   741     		self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys', '?action=regenerate',
       
   742     		Zend_Http_Client::POST,
       
   743     		array('Content-Type' => 'application/xml'),
       
   744     		'<?xml version="1.0" encoding="utf-8"?>
       
   745              <RegenerateKeys xmlns="http://schemas.microsoft.com/windowsazure">
       
   746                <KeyType>' . ucfirst($key) . '</KeyType>
       
   747              </RegenerateKeys>');
       
   748 
       
   749     	if ($response->isSuccessful()) {
       
   750 			$xmlService = $this->_parseResponse($response);
       
   751 
       
   752 			if (!is_null($xmlService)) {
       
   753 				return array(
       
   754 					(string)$xmlService->StorageServiceKeys->Primary,
       
   755 					(string)$xmlService->StorageServiceKeys->Secondary
       
   756 				);
       
   757 			}
       
   758 			return array();
       
   759 		} else {
       
   760 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   761 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   762 		}
       
   763     }
       
   764     
       
   765     /**
       
   766      * The List Hosted Services operation lists the hosted services available
       
   767      * under the current subscription.
       
   768      *
       
   769      * @return array An array of Zend_Service_WindowsAzure_Management_HostedServiceInstance
       
   770      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   771      */
       
   772     public function listHostedServices()
       
   773     {
       
   774     	$response = $this->_performRequest(self::OP_HOSTED_SERVICES);
       
   775 
       
   776     	if ($response->isSuccessful()) {
       
   777 			$result = $this->_parseResponse($response);
       
   778 			
       
   779     		if (!$result->HostedService) {
       
   780 				return array();
       
   781 			}
       
   782 		    if (count($result->HostedService) > 1) {
       
   783     		    $xmlServices = $result->HostedService;
       
   784     		} else {
       
   785     		    $xmlServices = array($result->HostedService);
       
   786     		}
       
   787     		
       
   788 			$services = array();
       
   789 			if (!is_null($xmlServices)) {	
       
   790 				
       
   791 				for ($i = 0; $i < count($xmlServices); $i++) {
       
   792 					$services[] = new Zend_Service_WindowsAzure_Management_HostedServiceInstance(
       
   793 					    (string)$xmlServices[$i]->Url,
       
   794 					    (string)$xmlServices[$i]->ServiceName
       
   795 					);
       
   796 				}
       
   797 			}
       
   798 			return $services;
       
   799 		} else {
       
   800 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   801 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   802 		}
       
   803     }
       
   804     
       
   805     /**
       
   806      * The Create Hosted Service operation creates a new hosted service in Windows Azure.
       
   807      * 
       
   808      * @param string $serviceName A name for the hosted service that is unique to the subscription.
       
   809      * @param string $label A label for the hosted service. The label may be up to 100 characters in length.
       
   810      * @param string $description A description for the hosted service. The description may be up to 1024 characters in length.
       
   811      * @param string $location Required if AffinityGroup is not specified. The location where the hosted service will be created. 
       
   812      * @param string $affinityGroup Required if Location is not specified. The name of an existing affinity group associated with this subscription.
       
   813      */
       
   814     public function createHostedService($serviceName, $label, $description = '', $location = null, $affinityGroup = null)
       
   815     {
       
   816     	if ($serviceName == '' || is_null($serviceName)) {
       
   817 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   818     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   819     	}
       
   820     	if ($label == '' || is_null($label)) {
       
   821 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   822     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
   823     	}
       
   824         if (strlen($label) > 100) {
       
   825 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   826     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
   827     	}
       
   828         if (strlen($description) > 1024) {
       
   829 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   830     		throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.');
       
   831     	}
       
   832     	if ( (is_null($location) && is_null($affinityGroup)) || (!is_null($location) && !is_null($affinityGroup)) ) {
       
   833 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   834     		throw new Zend_Service_WindowsAzure_Management_Exception('Please specify a location -or- an affinity group for the service.');
       
   835     	}
       
   836     	
       
   837     	$locationOrAffinityGroup = is_null($location)
       
   838     		? '<AffinityGroup>' . $affinityGroup . '</AffinityGroup>'
       
   839     		: '<Location>' . $location . '</Location>';
       
   840     	
       
   841         $response = $this->_performRequest(self::OP_HOSTED_SERVICES, '',
       
   842     		Zend_Http_Client::POST,
       
   843     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
   844     		'<CreateHostedService xmlns="http://schemas.microsoft.com/windowsazure"><ServiceName>' . $serviceName . '</ServiceName><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description>' . $locationOrAffinityGroup . '</CreateHostedService>');
       
   845  	
       
   846     	if (!$response->isSuccessful()) {
       
   847 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   848 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   849 		}
       
   850     }
       
   851     
       
   852     /**
       
   853      * The Update Hosted Service operation updates the label and/or the description for a hosted service in Windows Azure.
       
   854      * 
       
   855      * @param string $serviceName A name for the hosted service that is unique to the subscription.
       
   856      * @param string $label A label for the hosted service. The label may be up to 100 characters in length.
       
   857      * @param string $description A description for the hosted service. The description may be up to 1024 characters in length.
       
   858      */
       
   859     public function updateHostedService($serviceName, $label, $description = '')
       
   860     {
       
   861     	if ($serviceName == '' || is_null($serviceName)) {
       
   862 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   863     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   864     	}
       
   865     	if ($label == '' || is_null($label)) {
       
   866 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   867     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
   868     	}
       
   869         if (strlen($label) > 100) {
       
   870 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   871     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
   872     	}
       
   873     	
       
   874         $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '',
       
   875     		Zend_Http_Client::PUT,
       
   876     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
   877     		'<UpdateHostedService xmlns="http://schemas.microsoft.com/windowsazure"><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description></UpdateHostedService>');
       
   878  	
       
   879     	if (!$response->isSuccessful()) {
       
   880 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   881 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   882 		}
       
   883     }
       
   884     
       
   885     /**
       
   886      * The Delete Hosted Service operation deletes the specified hosted service in Windows Azure.
       
   887      * 
       
   888      * @param string $serviceName A name for the hosted service that is unique to the subscription.
       
   889      */
       
   890     public function deleteHostedService($serviceName)
       
   891     {
       
   892     	if ($serviceName == '' || is_null($serviceName)) {
       
   893 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   894     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   895     	}
       
   896     	
       
   897         $response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '', Zend_Http_Client::DELETE);
       
   898  	
       
   899     	if (!$response->isSuccessful()) {
       
   900 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   901 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   902 		}
       
   903     }
       
   904     
       
   905     /**
       
   906      * The Get Hosted Service Properties operation retrieves system properties
       
   907      * for the specified hosted service. These properties include the service
       
   908      * name and service type; the name of the affinity group to which the service
       
   909      * belongs, or its location if it is not part of an affinity group; and
       
   910      * optionally, information on the service's deployments.
       
   911      *
       
   912      * @param string $serviceName The name of your service.
       
   913      * @return Zend_Service_WindowsAzure_Management_HostedServiceInstance
       
   914      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   915      */
       
   916     public function getHostedServiceProperties($serviceName)
       
   917     {
       
   918     	if ($serviceName == '' || is_null($serviceName)) {
       
   919 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   920     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   921     	}
       
   922     	
       
   923     	$response = $this->_performRequest(self::OP_HOSTED_SERVICES . '/' . $serviceName, '?embed-detail=true');
       
   924 
       
   925     	if ($response->isSuccessful()) {
       
   926 			$xmlService = $this->_parseResponse($response);
       
   927 
       
   928 			if (!is_null($xmlService)) {
       
   929 				
       
   930 				$returnValue = new Zend_Service_WindowsAzure_Management_HostedServiceInstance(
       
   931 					(string)$xmlService->Url,
       
   932 					(string)$xmlService->ServiceName,
       
   933 					(string)$xmlService->HostedServiceProperties->Description,
       
   934 					(string)$xmlService->HostedServiceProperties->AffinityGroup,
       
   935 					(string)$xmlService->HostedServiceProperties->Location,
       
   936 					(string)$xmlService->HostedServiceProperties->Label
       
   937 				);
       
   938 				
       
   939 				// Deployments
       
   940 		    	if (count($xmlService->Deployments->Deployment) > 1) {
       
   941     		    	$xmlServices = $xmlService->Deployments->Deployment;
       
   942     			} else {
       
   943     		    	$xmlServices = array($xmlService->Deployments->Deployment);
       
   944     			}
       
   945     			
       
   946     			$deployments = array();
       
   947     			foreach ($xmlServices as $xmlDeployment) {
       
   948 					$deployments[] = $this->_convertXmlElementToDeploymentInstance($xmlDeployment);
       
   949     			}
       
   950 				$returnValue->Deployments = $deployments;
       
   951 				
       
   952 				return $returnValue;
       
   953 			}
       
   954 			return null;
       
   955 		} else {
       
   956 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   957 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   958 		}
       
   959     }
       
   960 
       
   961     /**
       
   962      * The Create Deployment operation uploads a new service package
       
   963      * and creates a new deployment on staging or production.
       
   964      * 
       
   965      * @param string $serviceName		The service name
       
   966      * @param string $deploymentSlot	The deployment slot (production or staging)
       
   967 	 * @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.
       
   968 	 * @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.
       
   969 	 * @param string $packageUrl        The service configuration file for the deployment.
       
   970 	 * @param string $configuration     A label for this deployment, up to 100 characters in length.
       
   971 	 * @param boolean $startDeployment  Indicates whether to start the deployment immediately after it is created.
       
   972 	 * @param boolean $treatWarningsAsErrors Indicates whether to treat package validation warnings as errors.
       
   973      * @throws Zend_Service_WindowsAzure_Management_Exception
       
   974      */
       
   975     public function createDeployment($serviceName, $deploymentSlot, $name, $label, $packageUrl, $configuration, $startDeployment = false, $treatWarningsAsErrors = false)
       
   976     {
       
   977         if ($serviceName == '' || is_null($serviceName)) {
       
   978 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   979     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
   980     	}
       
   981     	$deploymentSlot = strtolower($deploymentSlot);
       
   982     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
   983 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   984     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
   985     	}
       
   986     	if ($name == '' || is_null($name)) {
       
   987 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   988     		throw new Zend_Service_WindowsAzure_Management_Exception('Name should be specified.');
       
   989     	}
       
   990     	if ($label == '' || is_null($label)) {
       
   991 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   992     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
   993     	}
       
   994         if (strlen($label) > 100) {
       
   995 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
   996     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
   997     	}
       
   998     	if ($packageUrl == '' || is_null($packageUrl)) {
       
   999 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1000     		throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.');
       
  1001     	}
       
  1002     	if ($configuration == '' || is_null($configuration)) {
       
  1003 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1004     		throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.');
       
  1005     	}
       
  1006     	
       
  1007     	if (@file_exists($configuration)) {
       
  1008     		$configuration = utf8_decode(file_get_contents($configuration));
       
  1009     	}
       
  1010     	
       
  1011     	// Clean up the configuration
       
  1012     	$conformingConfiguration = $this->_cleanConfiguration($configuration);
       
  1013     	
       
  1014     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1015         $response = $this->_performRequest($operationUrl, '',
       
  1016     		Zend_Http_Client::POST,
       
  1017     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  1018     		'<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>');
       
  1019  	
       
  1020     	if (!$response->isSuccessful()) {
       
  1021 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1022 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1023 		}    	
       
  1024     }
       
  1025     
       
  1026     /**
       
  1027      * The Get Deployment operation returns configuration information, status,
       
  1028      * and system properties for the specified deployment.
       
  1029      * 
       
  1030      * @param string $serviceName		The service name
       
  1031      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1032      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
       
  1033      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1034      */
       
  1035     public function getDeploymentBySlot($serviceName, $deploymentSlot)
       
  1036     {
       
  1037         if ($serviceName == '' || is_null($serviceName)) {
       
  1038 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1039     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1040     	}
       
  1041     	$deploymentSlot = strtolower($deploymentSlot);
       
  1042     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1043 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1044     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1045     	}
       
  1046     	
       
  1047     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1048     	return $this->_getDeployment($operationUrl);
       
  1049     }
       
  1050     
       
  1051     /**
       
  1052      * The Get Deployment operation returns configuration information, status,
       
  1053      * and system properties for the specified deployment.
       
  1054      * 
       
  1055      * @param string $serviceName		The service name
       
  1056      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1057      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
       
  1058      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1059      */
       
  1060     public function getDeploymentByDeploymentId($serviceName, $deploymentId)
       
  1061     {
       
  1062         if ($serviceName == '' || is_null($serviceName)) {
       
  1063 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1064     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1065     	}
       
  1066         if ($deploymentId == '' || is_null($deploymentId)) {
       
  1067 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1068     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1069     	}
       
  1070     	
       
  1071     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
       
  1072     	return $this->_getDeployment($operationUrl);
       
  1073     }
       
  1074     
       
  1075     /**
       
  1076      * The Get Deployment operation returns configuration information, status,
       
  1077      * and system properties for the specified deployment.
       
  1078      * 
       
  1079      * @param string $operationUrl		The operation url
       
  1080      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
       
  1081      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1082      */
       
  1083     protected function _getDeployment($operationUrl)
       
  1084     {
       
  1085         $response = $this->_performRequest($operationUrl);
       
  1086 
       
  1087     	if ($response->isSuccessful()) {
       
  1088 			$xmlService = $this->_parseResponse($response);
       
  1089 			
       
  1090 			return $this->_convertXmlElementToDeploymentInstance($xmlService);
       
  1091 		} else {
       
  1092 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1093 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1094 		}
       
  1095     }
       
  1096     
       
  1097     /**
       
  1098      * The Swap Deployment operation initiates a virtual IP swap between
       
  1099      * the staging and production deployment environments for a service.
       
  1100      * If the service is currently running in the staging environment,
       
  1101      * it will be swapped to the production environment. If it is running
       
  1102      * in the production environment, it will be swapped to staging.
       
  1103      * 
       
  1104      * @param string $serviceName The service name.
       
  1105      * @param string $productionDeploymentName The name of the production deployment.
       
  1106      * @param string $sourceDeploymentName The name of the source deployment.
       
  1107      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1108      */
       
  1109     public function swapDeployment($serviceName, $productionDeploymentName, $sourceDeploymentName)
       
  1110     {
       
  1111     	if ($serviceName == '' || is_null($serviceName)) {
       
  1112 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1113     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1114     	}
       
  1115     	if ($productionDeploymentName == '' || is_null($productionDeploymentName)) {
       
  1116 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1117     		throw new Zend_Service_WindowsAzure_Management_Exception('Production Deployment ID should be specified.');
       
  1118     	}
       
  1119     	if ($sourceDeploymentName == '' || is_null($sourceDeploymentName)) {
       
  1120 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1121     		throw new Zend_Service_WindowsAzure_Management_Exception('Source Deployment ID should be specified.');
       
  1122     	}
       
  1123     	
       
  1124     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName;
       
  1125         $response = $this->_performRequest($operationUrl, '',
       
  1126     		Zend_Http_Client::POST,
       
  1127     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  1128     		'<Swap xmlns="http://schemas.microsoft.com/windowsazure"><Production>' . $productionDeploymentName . '</Production><SourceDeployment>' . $sourceDeploymentName . '</SourceDeployment></Swap>');
       
  1129     		
       
  1130     	if (!$response->isSuccessful()) {
       
  1131 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1132 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1133 		}    	
       
  1134     }
       
  1135     
       
  1136     /**
       
  1137      * The Delete Deployment operation deletes the specified deployment.
       
  1138      * 
       
  1139      * @param string $serviceName		The service name
       
  1140      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1141      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1142      */
       
  1143     public function deleteDeploymentBySlot($serviceName, $deploymentSlot)
       
  1144     {
       
  1145         if ($serviceName == '' || is_null($serviceName)) {
       
  1146 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1147     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1148     	}
       
  1149     	$deploymentSlot = strtolower($deploymentSlot);
       
  1150     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1151 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1152     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1153     	}
       
  1154     	
       
  1155     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1156     	return $this->_deleteDeployment($operationUrl);
       
  1157     }
       
  1158     
       
  1159     /**
       
  1160      * The Delete Deployment operation deletes the specified deployment.
       
  1161      * 
       
  1162      * @param string $serviceName		The service name
       
  1163      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1164      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1165      */
       
  1166     public function deleteDeploymentByDeploymentId($serviceName, $deploymentId)
       
  1167     {
       
  1168         if ($serviceName == '' || is_null($serviceName)) {
       
  1169 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1170     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1171     	}
       
  1172     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1173 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1174     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1175     	}
       
  1176     	
       
  1177     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
       
  1178     	return $this->_deleteDeployment($operationUrl);
       
  1179     }
       
  1180     
       
  1181     /**
       
  1182      * The Delete Deployment operation deletes the specified deployment.
       
  1183      * 
       
  1184      * @param string $operationUrl		The operation url
       
  1185      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1186      */
       
  1187     protected function _deleteDeployment($operationUrl)
       
  1188     {
       
  1189         $response = $this->_performRequest($operationUrl, '', Zend_Http_Client::DELETE);
       
  1190 			 
       
  1191     	if (!$response->isSuccessful()) {
       
  1192 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1193 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1194 		}
       
  1195     }
       
  1196     
       
  1197     /**
       
  1198      * The Update Deployment Status operation initiates a change in deployment status.
       
  1199      * 
       
  1200      * @param string $serviceName		The service name
       
  1201      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1202      * @param string $status            The deployment status (running|suspended)
       
  1203      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1204      */
       
  1205     public function updateDeploymentStatusBySlot($serviceName, $deploymentSlot, $status = 'running')
       
  1206     {
       
  1207         if ($serviceName == '' || is_null($serviceName)) {
       
  1208 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1209     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1210     	}
       
  1211     	$deploymentSlot = strtolower($deploymentSlot);
       
  1212     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1213 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1214     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1215     	}
       
  1216     	$status = strtolower($status);
       
  1217     	if ($status != 'running' && $status != 'suspended') {
       
  1218 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1219     		throw new Zend_Service_WindowsAzure_Management_Exception('Status should be running|suspended.');
       
  1220     	}
       
  1221     	
       
  1222     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1223     	return $this->_updateDeploymentStatus($operationUrl, $status);
       
  1224     }
       
  1225     
       
  1226     /**
       
  1227      * The Update Deployment Status operation initiates a change in deployment status.
       
  1228      * 
       
  1229      * @param string $serviceName		The service name
       
  1230      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1231      * @param string $status            The deployment status (running|suspended)
       
  1232      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1233      */
       
  1234     public function updateDeploymentStatusByDeploymentId($serviceName, $deploymentId, $status = 'running')
       
  1235     {
       
  1236         if ($serviceName == '' || is_null($serviceName)) {
       
  1237 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1238     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1239     	}
       
  1240     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1241 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1242     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1243     	}
       
  1244         $status = strtolower($status);
       
  1245     	if ($status != 'running' && $status != 'suspended') {
       
  1246 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1247     		throw new Zend_Service_WindowsAzure_Management_Exception('Status should be running|suspended.');
       
  1248     	}
       
  1249     	
       
  1250     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
       
  1251     	return $this->_updateDeploymentStatus($operationUrl, $status);
       
  1252     }
       
  1253     
       
  1254     /**
       
  1255      * The Update Deployment Status operation initiates a change in deployment status.
       
  1256      * 
       
  1257      * @param string $operationUrl		The operation url
       
  1258      * @param string $status            The deployment status (running|suspended)
       
  1259      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1260      */
       
  1261     protected function _updateDeploymentStatus($operationUrl, $status = 'running')
       
  1262     {
       
  1263         $response = $this->_performRequest($operationUrl . '/', '?comp=status',
       
  1264     		Zend_Http_Client::POST,
       
  1265     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  1266     		'<UpdateDeploymentStatus xmlns="http://schemas.microsoft.com/windowsazure"><Status>' . ucfirst($status) . '</Status></UpdateDeploymentStatus>');
       
  1267     		
       
  1268     	if (!$response->isSuccessful()) {
       
  1269 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1270 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1271 		}
       
  1272     }
       
  1273     
       
  1274     /**
       
  1275      * Converts an XmlElement into a Zend_Service_WindowsAzure_Management_DeploymentInstance
       
  1276      * 
       
  1277      * @param object $xmlService The XML Element
       
  1278      * @return Zend_Service_WindowsAzure_Management_DeploymentInstance
       
  1279      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1280      */
       
  1281     protected function _convertXmlElementToDeploymentInstance($xmlService)
       
  1282     {
       
  1283 		if (!is_null($xmlService)) {
       
  1284 			
       
  1285 			$returnValue = new Zend_Service_WindowsAzure_Management_DeploymentInstance(
       
  1286 				(string)$xmlService->Name,
       
  1287 				(string)$xmlService->DeploymentSlot,
       
  1288 				(string)$xmlService->PrivateID,
       
  1289 				(string)$xmlService->Label,
       
  1290 				(string)$xmlService->Url,
       
  1291 				(string)$xmlService->Configuration,
       
  1292 				(string)$xmlService->Status,
       
  1293 				(string)$xmlService->UpgradeStatus,
       
  1294 				(string)$xmlService->UpgradeType,
       
  1295 				(string)$xmlService->CurrentUpgradeDomainState,
       
  1296 				(string)$xmlService->CurrentUpgradeDomain,
       
  1297 				(string)$xmlService->UpgradeDomainCount
       
  1298 			);
       
  1299 				
       
  1300 			// Append role instances
       
  1301 			if ($xmlService->RoleInstanceList && $xmlService->RoleInstanceList->RoleInstance) {
       
  1302 				$xmlRoleInstances = $xmlService->RoleInstanceList->RoleInstance;
       
  1303 				if (count($xmlService->RoleInstanceList->RoleInstance) == 1) {
       
  1304 		    	    $xmlRoleInstances = array($xmlService->RoleInstanceList->RoleInstance);
       
  1305 		    	}
       
  1306 		    		
       
  1307 				$roleInstances = array();
       
  1308 				if (!is_null($xmlRoleInstances)) {				
       
  1309 					for ($i = 0; $i < count($xmlRoleInstances); $i++) {
       
  1310 						$roleInstances[] = array(
       
  1311 						    'rolename' => (string)$xmlRoleInstances[$i]->RoleName,
       
  1312 						    'instancename' => (string)$xmlRoleInstances[$i]->InstanceName,
       
  1313 						    'instancestatus' => (string)$xmlRoleInstances[$i]->InstanceStatus
       
  1314 						);
       
  1315 					}
       
  1316 				}
       
  1317 				
       
  1318 				$returnValue->RoleInstanceList = $roleInstances;
       
  1319 			}
       
  1320 			
       
  1321 			// Append roles
       
  1322 			if ($xmlService->RoleList && $xmlService->RoleList->Role) {
       
  1323 				$xmlRoles = $xmlService->RoleList->Role;
       
  1324 				if (count($xmlService->RoleList->Role) == 1) {
       
  1325 		    	    $xmlRoles = array($xmlService->RoleList->Role);
       
  1326 		    	}
       
  1327 	    		
       
  1328 				$roles = array();
       
  1329 				if (!is_null($xmlRoles)) {				
       
  1330 					for ($i = 0; $i < count($xmlRoles); $i++) {
       
  1331 						$roles[] = array(
       
  1332 						    'rolename' => (string)$xmlRoles[$i]->RoleName,
       
  1333 						    'osversion' => (!is_null($xmlRoles[$i]->OsVersion) ? (string)$xmlRoles[$i]->OsVersion : (string)$xmlRoles[$i]->OperatingSystemVersion)					
       
  1334 						);
       
  1335 					}
       
  1336 				}
       
  1337 				$returnValue->RoleList = $roles;
       
  1338 			}
       
  1339 				
       
  1340 			return $returnValue;
       
  1341 		}
       
  1342 		return null;
       
  1343     }
       
  1344     
       
  1345     /**
       
  1346      * Updates a deployment's role instance count.
       
  1347      * 
       
  1348      * @param string $serviceName		The service name
       
  1349      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1350      * @param string|array $roleName	The role name
       
  1351      * @param string|array $instanceCount The instance count
       
  1352      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1353      */
       
  1354 	public function setInstanceCountBySlot($serviceName, $deploymentSlot, $roleName, $instanceCount) {
       
  1355 	    if ($serviceName == '' || is_null($serviceName)) {
       
  1356 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1357     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1358     	}
       
  1359     	$deploymentSlot = strtolower($deploymentSlot);
       
  1360     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1361 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1362     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1363     	}
       
  1364     	if ($roleName == '' || is_null($roleName)) {
       
  1365 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1366     		throw new Zend_Service_WindowsAzure_Management_Exception('Role name name should be specified.');
       
  1367     	}
       
  1368     	
       
  1369 		// Get configuration
       
  1370 		$deployment = $this->getDeploymentBySlot($serviceName, $deploymentSlot);
       
  1371 		$configuration = $deployment->Configuration;
       
  1372 		$configuration = $this->_updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration);
       
  1373 		
       
  1374 		// Update configuration
       
  1375 		$this->configureDeploymentBySlot($serviceName, $deploymentSlot, $configuration);		
       
  1376 	}
       
  1377 	
       
  1378     /**
       
  1379      * Updates a deployment's role instance count.
       
  1380      * 
       
  1381      * @param string $serviceName		The service name
       
  1382      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1383      * @param string|array $roleName	The role name
       
  1384      * @param string|array $instanceCount The instance count
       
  1385      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1386      */
       
  1387     public function setInstanceCountByDeploymentId($serviceName, $deploymentId, $roleName, $instanceCount)
       
  1388     {
       
  1389 	    if ($serviceName == '' || is_null($serviceName)) {
       
  1390 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1391     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1392     	}
       
  1393         if ($deploymentId == '' || is_null($deploymentId)) {
       
  1394 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1395     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1396     	}
       
  1397     	if ($roleName == '' || is_null($roleName)) {
       
  1398 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1399     		throw new Zend_Service_WindowsAzure_Management_Exception('Role name name should be specified.');
       
  1400     	}
       
  1401     	
       
  1402 		// Get configuration
       
  1403 		$deployment = $this->getDeploymentByDeploymentId($serviceName, $deploymentId);
       
  1404 		$configuration = $deployment->Configuration;
       
  1405 		$configuration = $this->_updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration);
       
  1406 		
       
  1407 		// Update configuration
       
  1408 		$this->configureDeploymentByDeploymentId($serviceName, $deploymentId, $configuration);
       
  1409     }
       
  1410 	
       
  1411     /**
       
  1412      * Updates instance count in configuration XML.
       
  1413      * 
       
  1414      * @param string|array $roleName			The role name
       
  1415      * @param string|array $instanceCount		The instance count
       
  1416      * @param string $configuration             XML configuration represented as a string
       
  1417      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1418      */
       
  1419 	protected function _updateInstanceCountInConfiguration($roleName, $instanceCount, $configuration) {
       
  1420     	// Change variables
       
  1421 		if (!is_array($roleName)) {
       
  1422 			$roleName = array($roleName);
       
  1423 		}
       
  1424 		if (!is_array($instanceCount)) {
       
  1425 			$instanceCount = array($instanceCount);
       
  1426 		}
       
  1427 
       
  1428 		$configuration = preg_replace('/(<\?xml[^?]+?)utf-16/i', '$1utf-8', $configuration);
       
  1429 		//$configuration = '<?xml version="1.0">' . substr($configuration, strpos($configuration, '>') + 2);
       
  1430 
       
  1431 		$xml = simplexml_load_string($configuration); 
       
  1432 		
       
  1433 		// http://www.php.net/manual/en/simplexmlelement.xpath.php#97818
       
  1434 		$namespaces = $xml->getDocNamespaces();
       
  1435 	    $xml->registerXPathNamespace('__empty_ns', $namespaces['']); 
       
  1436 	
       
  1437 		for ($i = 0; $i < count($roleName); $i++) {
       
  1438 			$elements = $xml->xpath('//__empty_ns:Role[@name="' . $roleName[$i] . '"]/__empty_ns:Instances');
       
  1439 	
       
  1440 			if (count($elements) == 1) {
       
  1441 				$element = $elements[0];
       
  1442 				$element['count'] = $instanceCount[$i];
       
  1443 			} 
       
  1444 		}
       
  1445 		
       
  1446 		$configuration = $xml->asXML();
       
  1447 		//$configuration = preg_replace('/(<\?xml[^?]+?)utf-8/i', '$1utf-16', $configuration);
       
  1448 
       
  1449 		return $configuration;
       
  1450 	}
       
  1451     
       
  1452     /**
       
  1453      * The Change Deployment Configuration request may be specified as follows.
       
  1454      * Note that you can change a deployment's configuration either by specifying the deployment
       
  1455      * environment (staging or production), or by specifying the deployment's unique name. 
       
  1456      * 
       
  1457      * @param string $serviceName		The service name
       
  1458      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1459      * @param string $configuration     XML configuration represented as a string
       
  1460      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1461      */
       
  1462     public function configureDeploymentBySlot($serviceName, $deploymentSlot, $configuration)
       
  1463     {
       
  1464         if ($serviceName == '' || is_null($serviceName)) {
       
  1465 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1466     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1467     	}
       
  1468     	$deploymentSlot = strtolower($deploymentSlot);
       
  1469     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1470 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1471     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1472     	}
       
  1473     	if ($configuration == '' || is_null($configuration)) {
       
  1474 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1475     		throw new Zend_Service_WindowsAzure_Management_Exception('Configuration name should be specified.');
       
  1476     	}
       
  1477     	
       
  1478         if (@file_exists($configuration)) {
       
  1479     		$configuration = utf8_decode(file_get_contents($configuration));
       
  1480     	}
       
  1481     	
       
  1482     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1483     	return $this->_configureDeployment($operationUrl, $configuration);
       
  1484     }
       
  1485     
       
  1486     /**
       
  1487      * The Change Deployment Configuration request may be specified as follows.
       
  1488      * Note that you can change a deployment's configuration either by specifying the deployment
       
  1489      * environment (staging or production), or by specifying the deployment's unique name. 
       
  1490      * 
       
  1491      * @param string $serviceName		The service name
       
  1492      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1493      * @param string $configuration     XML configuration represented as a string
       
  1494      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1495      */
       
  1496     public function configureDeploymentByDeploymentId($serviceName, $deploymentId, $configuration)
       
  1497     {
       
  1498         if ($serviceName == '' || is_null($serviceName)) {
       
  1499 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1500     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1501     	}
       
  1502     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1503 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1504     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1505     	}
       
  1506     	if ($configuration == '' || is_null($configuration)) {
       
  1507 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1508     		throw new Zend_Service_WindowsAzure_Management_Exception('Configuration name should be specified.');
       
  1509     	}
       
  1510     	
       
  1511         if (@file_exists($configuration)) {
       
  1512     		$configuration = utf8_decode(file_get_contents($configuration));
       
  1513     	}
       
  1514     	
       
  1515     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
       
  1516     	return $this->_configureDeployment($operationUrl, $configuration);
       
  1517     }
       
  1518     
       
  1519     /**
       
  1520      * The Change Deployment Configuration request may be specified as follows.
       
  1521      * Note that you can change a deployment's configuration either by specifying the deployment
       
  1522      * environment (staging or production), or by specifying the deployment's unique name. 
       
  1523      * 
       
  1524      * @param string $operationUrl		The operation url
       
  1525      * @param string $configuration     XML configuration represented as a string
       
  1526      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1527      */
       
  1528     protected function _configureDeployment($operationUrl, $configuration)
       
  1529     {
       
  1530     	// Clean up the configuration
       
  1531     	$conformingConfiguration = $this->_cleanConfiguration($configuration);
       
  1532 
       
  1533         $response = $this->_performRequest($operationUrl . '/', '?comp=config',
       
  1534     		Zend_Http_Client::POST,
       
  1535     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  1536     		'<ChangeConfiguration xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Configuration>' . base64_encode($conformingConfiguration) . '</Configuration></ChangeConfiguration>');
       
  1537 			 
       
  1538     	if (!$response->isSuccessful()) {
       
  1539 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1540 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1541 		}
       
  1542     }
       
  1543     
       
  1544     /**
       
  1545      * The Upgrade Deployment operation initiates an upgrade.
       
  1546      * 
       
  1547      * @param string $serviceName		The service name
       
  1548      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1549 	 * @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.
       
  1550 	 * @param string $packageUrl        The service configuration file for the deployment.
       
  1551 	 * @param string $configuration     A label for this deployment, up to 100 characters in length.
       
  1552      * @param string $mode              The type of upgrade to initiate. Possible values are Auto or Manual.
       
  1553      * @param string $roleToUpgrade     The name of the specific role to upgrade.
       
  1554      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1555      */
       
  1556     public function upgradeDeploymentBySlot($serviceName, $deploymentSlot, $label, $packageUrl, $configuration, $mode = 'auto', $roleToUpgrade = null)
       
  1557     {
       
  1558         if ($serviceName == '' || is_null($serviceName)) {
       
  1559 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1560     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1561     	}
       
  1562     	$deploymentSlot = strtolower($deploymentSlot);
       
  1563     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1564 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1565     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1566     	}
       
  1567     	if ($label == '' || is_null($label)) {
       
  1568 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1569     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
  1570     	}
       
  1571         if (strlen($label) > 100) {
       
  1572 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1573     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
  1574     	}
       
  1575     	if ($packageUrl == '' || is_null($packageUrl)) {
       
  1576 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1577     		throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.');
       
  1578     	}
       
  1579     	if ($configuration == '' || is_null($configuration)) {
       
  1580 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1581     		throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.');
       
  1582     	}
       
  1583     	$mode = strtolower($mode);
       
  1584     	if ($mode != 'auto' && $mode != 'manual') {
       
  1585 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1586     		throw new Zend_Service_WindowsAzure_Management_Exception('Mode should be auto|manual.');
       
  1587     	}
       
  1588     	
       
  1589     	if (@file_exists($configuration)) {
       
  1590     		$configuration = utf8_decode(file_get_contents($configuration));
       
  1591     	}
       
  1592     	
       
  1593 		$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1594     	return $this->_upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade);  	
       
  1595     }
       
  1596     
       
  1597     /**
       
  1598      * The Upgrade Deployment operation initiates an upgrade.
       
  1599      * 
       
  1600      * @param string $serviceName		The service name
       
  1601      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1602 	 * @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.
       
  1603 	 * @param string $packageUrl        The service configuration file for the deployment.
       
  1604 	 * @param string $configuration     A label for this deployment, up to 100 characters in length.
       
  1605      * @param string $mode              The type of upgrade to initiate. Possible values are Auto or Manual.
       
  1606      * @param string $roleToUpgrade     The name of the specific role to upgrade.
       
  1607      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1608      */
       
  1609     public function upgradeDeploymentByDeploymentId($serviceName, $deploymentId, $label, $packageUrl, $configuration, $mode = 'auto', $roleToUpgrade = null)
       
  1610     {
       
  1611         if ($serviceName == '' || is_null($serviceName)) {
       
  1612 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1613     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1614     	}
       
  1615     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1616 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1617     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1618     	}
       
  1619     	if ($label == '' || is_null($label)) {
       
  1620 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1621     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
  1622     	}
       
  1623         if (strlen($label) > 100) {
       
  1624 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1625     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
  1626     	}
       
  1627     	if ($packageUrl == '' || is_null($packageUrl)) {
       
  1628 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1629     		throw new Zend_Service_WindowsAzure_Management_Exception('Package URL should be specified.');
       
  1630     	}
       
  1631     	if ($configuration == '' || is_null($configuration)) {
       
  1632 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1633     		throw new Zend_Service_WindowsAzure_Management_Exception('Configuration should be specified.');
       
  1634     	}
       
  1635     	$mode = strtolower($mode);
       
  1636     	if ($mode != 'auto' && $mode != 'manual') {
       
  1637 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1638     		throw new Zend_Service_WindowsAzure_Management_Exception('Mode should be auto|manual.');
       
  1639     	}
       
  1640     	
       
  1641     	if (@file_exists($configuration)) {
       
  1642     		$configuration = utf8_decode(file_get_contents($configuration));
       
  1643     	}
       
  1644     	
       
  1645 		$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
       
  1646     	return $this->_upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade);  	
       
  1647     }
       
  1648     
       
  1649     
       
  1650     /**
       
  1651      * The Upgrade Deployment operation initiates an upgrade.
       
  1652      * 
       
  1653      * @param string $operationUrl		The operation url
       
  1654 	 * @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.
       
  1655 	 * @param string $packageUrl        The service configuration file for the deployment.
       
  1656 	 * @param string $configuration     A label for this deployment, up to 100 characters in length.
       
  1657      * @param string $mode              The type of upgrade to initiate. Possible values are Auto or Manual.
       
  1658      * @param string $roleToUpgrade     The name of the specific role to upgrade.
       
  1659      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1660      */
       
  1661     protected function _upgradeDeployment($operationUrl, $label, $packageUrl, $configuration, $mode, $roleToUpgrade)
       
  1662     {
       
  1663     	// Clean up the configuration
       
  1664     	$conformingConfiguration = $this->_cleanConfiguration($configuration);
       
  1665     	
       
  1666         $response = $this->_performRequest($operationUrl . '/', '?comp=upgrade',
       
  1667     		Zend_Http_Client::POST,
       
  1668     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  1669     		'<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>');		
       
  1670     		
       
  1671     	if (!$response->isSuccessful()) {
       
  1672 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1673 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1674 		}
       
  1675     }
       
  1676     
       
  1677     /**
       
  1678      * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade.
       
  1679      * 
       
  1680      * @param string $serviceName		The service name
       
  1681      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1682 	 * @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.
       
  1683      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1684      */
       
  1685     public function walkUpgradeDomainBySlot($serviceName, $deploymentSlot, $upgradeDomain = 0)
       
  1686     {
       
  1687         if ($serviceName == '' || is_null($serviceName)) {
       
  1688 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1689     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1690     	}
       
  1691     	$deploymentSlot = strtolower($deploymentSlot);
       
  1692     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1693 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1694     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1695     	}
       
  1696     	
       
  1697 		$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot;
       
  1698     	return $this->_walkUpgradeDomain($operationUrl, $upgradeDomain);  	
       
  1699     }
       
  1700     
       
  1701     /**
       
  1702      * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade.
       
  1703      * 
       
  1704      * @param string $serviceName		The service name
       
  1705      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1706 	 * @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.
       
  1707      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1708      */
       
  1709     public function walkUpgradeDomainByDeploymentId($serviceName, $deploymentId, $upgradeDomain = 0)
       
  1710     {
       
  1711         if ($serviceName == '' || is_null($serviceName)) {
       
  1712 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1713     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1714     	}
       
  1715     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1716 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1717     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1718     	}
       
  1719     	
       
  1720 		$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId;
       
  1721     	return $this->_walkUpgradeDomain($operationUrl, $upgradeDomain);  	
       
  1722     }
       
  1723     
       
  1724     
       
  1725     /**
       
  1726      * The Walk Upgrade Domain operation specifies the next upgrade domain to be walked during an in-place upgrade.
       
  1727      * 
       
  1728      * @param string $operationUrl   The operation url
       
  1729 	 * @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.
       
  1730      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1731      */
       
  1732     protected function _walkUpgradeDomain($operationUrl, $upgradeDomain = 0)
       
  1733     {
       
  1734         $response = $this->_performRequest($operationUrl . '/', '?comp=walkupgradedomain',
       
  1735     		Zend_Http_Client::POST,
       
  1736     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  1737     		'<WalkUpgradeDomain xmlns="http://schemas.microsoft.com/windowsazure"><UpgradeDomain>' . $upgradeDomain . '</UpgradeDomain></WalkUpgradeDomain>');		
       
  1738 
       
  1739     	if (!$response->isSuccessful()) {
       
  1740 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1741 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1742 		}
       
  1743     }
       
  1744     
       
  1745     /**
       
  1746      * The Reboot Role Instance operation requests a reboot of a role instance
       
  1747      * that is running in a deployment.
       
  1748      * 
       
  1749      * @param string $serviceName		The service name
       
  1750      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1751      * @param string $roleInstanceName  The role instance name
       
  1752      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1753      */
       
  1754     public function rebootRoleInstanceBySlot($serviceName, $deploymentSlot, $roleInstanceName)
       
  1755     {
       
  1756         if ($serviceName == '' || is_null($serviceName)) {
       
  1757 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1758     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1759     	}
       
  1760     	$deploymentSlot = strtolower($deploymentSlot);
       
  1761     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1762 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1763     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1764     	}
       
  1765         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
       
  1766 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1767     		throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
       
  1768     	}
       
  1769     	
       
  1770     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot . '/roleinstances/' . $roleInstanceName;
       
  1771     	return $this->_rebootOrReimageRoleInstance($operationUrl, 'reboot');
       
  1772     }
       
  1773     
       
  1774     /**
       
  1775      * The Reboot Role Instance operation requests a reboot of a role instance
       
  1776      * that is running in a deployment.
       
  1777      * 
       
  1778      * @param string $serviceName		The service name
       
  1779      * @param string $deploymentId	The deployment ID as listed on the Windows Azure management portal
       
  1780      * @param string $roleInstanceName  The role instance name
       
  1781      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1782      */
       
  1783     public function rebootRoleInstanceByDeploymentId($serviceName, $deploymentId, $roleInstanceName)
       
  1784     {
       
  1785         if ($serviceName == '' || is_null($serviceName)) {
       
  1786 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1787     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1788     	}
       
  1789     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1790 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1791     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1792     	}
       
  1793         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
       
  1794 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1795     		throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
       
  1796     	}
       
  1797     	
       
  1798     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId . '/roleinstances/' . $roleInstanceName;
       
  1799     	return $this->_rebootOrReimageRoleInstance($operationUrl, 'reboot');
       
  1800     }
       
  1801 
       
  1802     /**
       
  1803      * The Reimage Role Instance operation requests a reimage of a role instance
       
  1804      * that is running in a deployment.
       
  1805      * 
       
  1806      * @param string $serviceName		The service name
       
  1807      * @param string $deploymentSlot	The deployment slot (production or staging)
       
  1808      * @param string $roleInstanceName  The role instance name
       
  1809      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1810      */
       
  1811     public function reimageRoleInstanceBySlot($serviceName, $deploymentSlot, $roleInstanceName)
       
  1812     {
       
  1813         if ($serviceName == '' || is_null($serviceName)) {
       
  1814 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1815     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1816     	}
       
  1817     	$deploymentSlot = strtolower($deploymentSlot);
       
  1818     	if ($deploymentSlot != 'production' && $deploymentSlot != 'staging') {
       
  1819 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1820     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment slot should be production|staging.');
       
  1821     	}
       
  1822         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
       
  1823 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1824     		throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
       
  1825     	}
       
  1826     	
       
  1827     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deploymentslots/' . $deploymentSlot . '/roleinstances/' . $roleInstanceName;
       
  1828     	return $this->_rebootOrReimageRoleInstance($operationUrl, 'reimage');
       
  1829     }
       
  1830     
       
  1831     /**
       
  1832      * The Reimage Role Instance operation requests a reimage of a role instance
       
  1833      * that is running in a deployment.
       
  1834      * 
       
  1835      * @param string $serviceName		The service name
       
  1836      * @param string $deploymentId	    The deployment ID as listed on the Windows Azure management portal
       
  1837      * @param string $roleInstanceName  The role instance name
       
  1838      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1839      */
       
  1840     public function reimageRoleInstanceByDeploymentId($serviceName, $deploymentId, $roleInstanceName)
       
  1841     {
       
  1842         if ($serviceName == '' || is_null($serviceName)) {
       
  1843 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1844     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1845     	}
       
  1846     	if ($deploymentId == '' || is_null($deploymentId)) {
       
  1847 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1848     		throw new Zend_Service_WindowsAzure_Management_Exception('Deployment ID should be specified.');
       
  1849     	}
       
  1850         if ($roleInstanceName == '' || is_null($roleInstanceName)) {
       
  1851 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1852     		throw new Zend_Service_WindowsAzure_Management_Exception('Role instance name should be specified.');
       
  1853     	}
       
  1854     	
       
  1855     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/deployments/' . $deploymentId . '/roleinstances/' . $roleInstanceName;
       
  1856     	return $this->_rebootOrReimageRoleInstance($operationUrl, 'reimage');
       
  1857     }
       
  1858     
       
  1859     /**
       
  1860      * Reboots or reimages a role instance.
       
  1861      * 
       
  1862      * @param string $operationUrl		The operation url
       
  1863      * @param string $operation The operation (reboot|reimage)
       
  1864      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1865      */
       
  1866     protected function _rebootOrReimageRoleInstance($operationUrl, $operation = 'reboot')
       
  1867     {
       
  1868         $response = $this->_performRequest($operationUrl, '?comp=' . $operation, Zend_Http_Client::POST);
       
  1869     		
       
  1870     	if (!$response->isSuccessful()) {
       
  1871 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1872 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1873 		}
       
  1874     }
       
  1875     
       
  1876     /**
       
  1877      * The List Certificates operation lists all certificates associated with
       
  1878      * the specified hosted service.
       
  1879      * 
       
  1880      * @param string $serviceName		The service name
       
  1881      * @return array Array of Zend_Service_WindowsAzure_Management_CertificateInstance
       
  1882      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1883      */
       
  1884     public function listCertificates($serviceName)
       
  1885     {
       
  1886         if ($serviceName == '' || is_null($serviceName)) {
       
  1887 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1888     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1889     	}
       
  1890     	
       
  1891     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates';
       
  1892         $response = $this->_performRequest($operationUrl);
       
  1893 
       
  1894     	if ($response->isSuccessful()) {
       
  1895 			$result = $this->_parseResponse($response);
       
  1896 
       
  1897 			if (!$result->Certificate) {
       
  1898 				return array();
       
  1899 			}
       
  1900 		    if (count($result->Certificate) > 1) {
       
  1901     		    $xmlServices = $result->Certificate;
       
  1902     		} else {
       
  1903     		    $xmlServices = array($result->Certificate);
       
  1904     		}
       
  1905 
       
  1906 			$services = array();
       
  1907 			if (!is_null($xmlServices)) {				
       
  1908 				
       
  1909 				for ($i = 0; $i < count($xmlServices); $i++) {
       
  1910 					$services[] = new Zend_Service_WindowsAzure_Management_CertificateInstance(
       
  1911 					    (string)$xmlServices[$i]->CertificateUrl,
       
  1912 					    (string)$xmlServices[$i]->Thumbprint,
       
  1913 					    (string)$xmlServices[$i]->ThumbprintAlgorithm,
       
  1914 					    (string)$xmlServices[$i]->Data
       
  1915 					);
       
  1916 				}
       
  1917 			}
       
  1918 			return $services;
       
  1919 		} else {
       
  1920 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1921 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1922 		}
       
  1923     }
       
  1924     
       
  1925     /**
       
  1926      * The Get Certificate operation returns the public data for the specified certificate.
       
  1927      * 
       
  1928      * @param string $serviceName|$certificateUrl	The service name -or- the certificate URL
       
  1929      * @param string $algorithm         			Algorithm
       
  1930      * @param string $thumbprint        			Thumbprint
       
  1931      * @return Zend_Service_WindowsAzure_Management_CertificateInstance
       
  1932      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1933      */
       
  1934     public function getCertificate($serviceName, $algorithm = '', $thumbprint = '')
       
  1935     {
       
  1936         if ($serviceName == '' || is_null($serviceName)) {
       
  1937 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1938     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name or certificate URL should be specified.');
       
  1939     	}
       
  1940     	if (strpos($serviceName, 'https') === false && ($algorithm == '' || is_null($algorithm)) && ($thumbprint == '' || is_null($thumbprint))) {
       
  1941 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1942     		throw new Zend_Service_WindowsAzure_Management_Exception('Algorithm and thumbprint should be specified.');
       
  1943     	}
       
  1944     	
       
  1945     	$operationUrl = str_replace($this->getBaseUrl(), '', $serviceName);
       
  1946     	if (strpos($serviceName, 'https') === false) {
       
  1947     		$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates/' . $algorithm . '-' . strtoupper($thumbprint);
       
  1948     	}
       
  1949     	
       
  1950         $response = $this->_performRequest($operationUrl);
       
  1951 
       
  1952     	if ($response->isSuccessful()) {
       
  1953 			$result = $this->_parseResponse($response);
       
  1954 			
       
  1955 			return new Zend_Service_WindowsAzure_Management_CertificateInstance(
       
  1956 				$this->getBaseUrl() . $operationUrl,
       
  1957 				$algorithm,
       
  1958 				$thumbprint,
       
  1959 				(string)$result->Data
       
  1960 			);
       
  1961 		} else {
       
  1962 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1963 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  1964 		}
       
  1965     }
       
  1966     
       
  1967     /**
       
  1968      * The Add Certificate operation adds a certificate to the subscription.
       
  1969      * 
       
  1970      * @param string $serviceName         The service name
       
  1971      * @param string $certificateData     Certificate data
       
  1972      * @param string $certificatePassword The certificate password
       
  1973      * @param string $certificateFormat   The certificate format. Currently, only 'pfx' is supported.
       
  1974      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  1975      */
       
  1976     public function addCertificate($serviceName, $certificateData, $certificatePassword, $certificateFormat = 'pfx')
       
  1977     {
       
  1978     	if ($serviceName == '' || is_null($serviceName)) {
       
  1979 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1980     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name should be specified.');
       
  1981     	}
       
  1982     	if ($certificateData == '' || is_null($certificateData)) {
       
  1983 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1984     		throw new Zend_Service_WindowsAzure_Management_Exception('Certificate data should be specified.');
       
  1985     	}
       
  1986     	if ($certificatePassword == '' || is_null($certificatePassword)) {
       
  1987 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1988     		throw new Zend_Service_WindowsAzure_Management_Exception('Certificate password should be specified.');
       
  1989     	}
       
  1990     	if ($certificateFormat != 'pfx') {
       
  1991 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  1992     		throw new Zend_Service_WindowsAzure_Management_Exception('Certificate format should be "pfx".');
       
  1993     	}
       
  1994     	
       
  1995     	if (@file_exists($certificateData)) {
       
  1996     		$certificateData = file_get_contents($certificateData);
       
  1997     	}
       
  1998     	
       
  1999     	$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates';
       
  2000         $response = $this->_performRequest($operationUrl, '',
       
  2001     		Zend_Http_Client::POST,
       
  2002     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  2003     		'<CertificateFile xmlns="http://schemas.microsoft.com/windowsazure"><Data>' . base64_encode($certificateData) . '</Data><CertificateFormat>' . $certificateFormat . '</CertificateFormat><Password>' . $certificatePassword . '</Password></CertificateFile>');
       
  2004 
       
  2005     	if (!$response->isSuccessful()) {
       
  2006 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2007 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2008 		}
       
  2009     }
       
  2010     
       
  2011     /**
       
  2012      * The Delete Certificate operation deletes a certificate from the subscription's certificate store.
       
  2013      * 
       
  2014      * @param string $serviceName|$certificateUrl	The service name -or- the certificate URL
       
  2015      * @param string $algorithm         			Algorithm
       
  2016      * @param string $thumbprint        			Thumbprint
       
  2017      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  2018      */
       
  2019     public function deleteCertificate($serviceName, $algorithm = '', $thumbprint = '')
       
  2020     {
       
  2021         if ($serviceName == '' || is_null($serviceName)) {
       
  2022 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2023     		throw new Zend_Service_WindowsAzure_Management_Exception('Service name or certificate URL should be specified.');
       
  2024     	}
       
  2025     	if (strpos($serviceName, 'https') === false && ($algorithm == '' || is_null($algorithm)) && ($thumbprint == '' || is_null($thumbprint))) {
       
  2026 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2027     		throw new Zend_Service_WindowsAzure_Management_Exception('Algorithm and thumbprint should be specified.');
       
  2028     	}
       
  2029     	
       
  2030     	$operationUrl = str_replace($this->getBaseUrl(), '', $serviceName);
       
  2031     	if (strpos($serviceName, 'https') === false) {
       
  2032     		$operationUrl = self::OP_HOSTED_SERVICES . '/' . $serviceName . '/certificates/' . $algorithm . '-' . strtoupper($thumbprint);
       
  2033     	}
       
  2034     	
       
  2035         $response = $this->_performRequest($operationUrl, '', Zend_Http_Client::DELETE);
       
  2036 
       
  2037     	if (!$response->isSuccessful()) {
       
  2038 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2039 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2040 		}
       
  2041     }
       
  2042     
       
  2043     /**
       
  2044      * The List Affinity Groups operation lists the affinity groups associated with
       
  2045      * the specified subscription.
       
  2046      * 
       
  2047      * @return array Array of Zend_Service_WindowsAzure_Management_AffinityGroupInstance
       
  2048      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  2049      */
       
  2050     public function listAffinityGroups()
       
  2051     {
       
  2052         $response = $this->_performRequest(self::OP_AFFINITYGROUPS);
       
  2053 
       
  2054     	if ($response->isSuccessful()) {
       
  2055 			$result = $this->_parseResponse($response);
       
  2056 			
       
  2057     		if (!$result->AffinityGroup) {
       
  2058 				return array();
       
  2059 			}
       
  2060 		    if (count($result->AffinityGroup) > 1) {
       
  2061     		    $xmlServices = $result->AffinityGroup;
       
  2062     		} else {
       
  2063     		    $xmlServices = array($result->AffinityGroup);
       
  2064     		}
       
  2065     		
       
  2066 			$services = array();
       
  2067 			if (!is_null($xmlServices)) {				
       
  2068 				
       
  2069 				for ($i = 0; $i < count($xmlServices); $i++) {
       
  2070 					$services[] = new Zend_Service_WindowsAzure_Management_AffinityGroupInstance(
       
  2071 					    (string)$xmlServices[$i]->Name,
       
  2072 					    (string)$xmlServices[$i]->Label,
       
  2073 					    (string)$xmlServices[$i]->Description,
       
  2074 					    (string)$xmlServices[$i]->Location
       
  2075 					);
       
  2076 				}
       
  2077 			}
       
  2078 			return $services;
       
  2079 		} else {
       
  2080 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2081 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2082 		}
       
  2083     }
       
  2084     
       
  2085     /**
       
  2086      * The Create Affinity Group operation creates a new affinity group for the specified subscription.
       
  2087      * 
       
  2088      * @param string $name A name for the affinity group that is unique to the subscription.
       
  2089      * @param string $label A label for the affinity group. The label may be up to 100 characters in length.
       
  2090      * @param string $description A description for the affinity group. The description may be up to 1024 characters in length.
       
  2091      * @param string $location The location where the affinity group will be created. To list available locations, use the List Locations operation. 
       
  2092      */
       
  2093     public function createAffinityGroup($name, $label, $description = '', $location = '')
       
  2094     {
       
  2095     	if ($name == '' || is_null($name)) {
       
  2096 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2097     		throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
       
  2098     	}
       
  2099     	if ($label == '' || is_null($label)) {
       
  2100 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2101     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
  2102     	}
       
  2103         if (strlen($label) > 100) {
       
  2104 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2105     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
  2106     	}
       
  2107         if (strlen($description) > 1024) {
       
  2108 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2109     		throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.');
       
  2110     	}
       
  2111     	if ($location == '' || is_null($location)) {
       
  2112 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2113     		throw new Zend_Service_WindowsAzure_Management_Exception('Location should be specified.');
       
  2114     	}
       
  2115     	
       
  2116         $response = $this->_performRequest(self::OP_AFFINITYGROUPS, '',
       
  2117     		Zend_Http_Client::POST,
       
  2118     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  2119     		'<CreateAffinityGroup xmlns="http://schemas.microsoft.com/windowsazure"><Name>' . $name . '</Name><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description><Location>' . $location . '</Location></CreateAffinityGroup>');	
       
  2120     		
       
  2121     	if (!$response->isSuccessful()) {
       
  2122 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2123 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2124 		}
       
  2125     }
       
  2126     
       
  2127     /**
       
  2128      * The Update Affinity Group operation updates the label and/or the description for an affinity group for the specified subscription.
       
  2129      * 
       
  2130      * @param string $name The name for the affinity group that should be updated.
       
  2131      * @param string $label A label for the affinity group. The label may be up to 100 characters in length.
       
  2132      * @param string $description A description for the affinity group. The description may be up to 1024 characters in length. 
       
  2133      */
       
  2134     public function updateAffinityGroup($name, $label, $description = '')
       
  2135     {
       
  2136     	if ($name == '' || is_null($name)) {
       
  2137 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2138     		throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
       
  2139     	}
       
  2140     	if ($label == '' || is_null($label)) {
       
  2141 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2142     		throw new Zend_Service_WindowsAzure_Management_Exception('Label should be specified.');
       
  2143     	}
       
  2144         if (strlen($label) > 100) {
       
  2145 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2146     		throw new Zend_Service_WindowsAzure_Management_Exception('Label is too long. The maximum length is 100 characters.');
       
  2147     	}
       
  2148         if (strlen($description) > 1024) {
       
  2149 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2150     		throw new Zend_Service_WindowsAzure_Management_Exception('Description is too long. The maximum length is 1024 characters.');
       
  2151     	}
       
  2152     	
       
  2153         $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $name, '',
       
  2154     		Zend_Http_Client::PUT,
       
  2155     		array('Content-Type' => 'application/xml; charset=utf-8'),
       
  2156     		'<UpdateAffinityGroup xmlns="http://schemas.microsoft.com/windowsazure"><Label>' . base64_encode($label) . '</Label><Description>' . $description . '</Description></UpdateAffinityGroup>');	
       
  2157     		
       
  2158     	if (!$response->isSuccessful()) {
       
  2159 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2160 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2161 		}
       
  2162     }
       
  2163     
       
  2164     /**
       
  2165      * The Delete Affinity Group operation deletes an affinity group in the specified subscription.
       
  2166      * 
       
  2167      * @param string $name The name for the affinity group that should be deleted.
       
  2168      */
       
  2169     public function deleteAffinityGroup($name)
       
  2170     {
       
  2171     	if ($name == '' || is_null($name)) {
       
  2172 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2173     		throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
       
  2174     	}
       
  2175     	
       
  2176         $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $name, '',
       
  2177     		Zend_Http_Client::DELETE);
       
  2178     		
       
  2179     	if (!$response->isSuccessful()) {
       
  2180 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2181 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2182 		}
       
  2183     }
       
  2184     
       
  2185     /**
       
  2186      * The Get Affinity Group Properties operation returns the
       
  2187      * system properties associated with the specified affinity group.
       
  2188      * 
       
  2189      * @param string $affinityGroupName The affinity group name.
       
  2190      * @return Zend_Service_WindowsAzure_Management_AffinityGroupInstance
       
  2191      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  2192      */
       
  2193     public function getAffinityGroupProperties($affinityGroupName)
       
  2194     {
       
  2195         if ($affinityGroupName == '' || is_null($affinityGroupName)) {
       
  2196 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2197     		throw new Zend_Service_WindowsAzure_Management_Exception('Affinity group name should be specified.');
       
  2198     	}
       
  2199     	
       
  2200         $response = $this->_performRequest(self::OP_AFFINITYGROUPS . '/' . $affinityGroupName);
       
  2201 
       
  2202     	if ($response->isSuccessful()) {
       
  2203 			$result = $this->_parseResponse($response);
       
  2204 			
       
  2205 			$affinityGroup = new Zend_Service_WindowsAzure_Management_AffinityGroupInstance(
       
  2206 				$affinityGroupName,
       
  2207 				(string)$result->Label,
       
  2208 				(string)$result->Description,
       
  2209 				(string)$result->Location
       
  2210 			);
       
  2211 
       
  2212 			// Hosted services
       
  2213 			if (count($result->HostedServices->HostedService) > 1) {
       
  2214 		    	$xmlService = $result->HostedServices->HostedService;
       
  2215 		    } else {
       
  2216 		    	$xmlService = array($result->HostedServices->HostedService);
       
  2217 		    }
       
  2218 		    		
       
  2219 			$services = array();
       
  2220 			if (!is_null($xmlService)) {				
       
  2221 				for ($i = 0; $i < count($xmlService); $i++) {
       
  2222 					$services[] = array(
       
  2223 						'url' => (string)$xmlService[$i]->Url,
       
  2224 						'name' => (string)$xmlService[$i]->ServiceName
       
  2225 					);
       
  2226 				}
       
  2227 			}
       
  2228 			$affinityGroup->HostedServices = $services;
       
  2229 			
       
  2230 			// Storage services
       
  2231 			if (count($result->StorageServices->StorageService) > 1) {
       
  2232 		    	$xmlService = $result->StorageServices->StorageService;
       
  2233 		    } else {
       
  2234 		    	$xmlService = array($result->StorageServices->StorageService);
       
  2235 		    }
       
  2236 		    		
       
  2237 			$services = array();
       
  2238 			if (!is_null($xmlService)) {				
       
  2239 				for ($i = 0; $i < count($xmlService); $i++) {
       
  2240 					$services[] = array(
       
  2241 						'url' => (string)$xmlService[$i]->Url,
       
  2242 						'name' => (string)$xmlService[$i]->ServiceName
       
  2243 					);
       
  2244 				}
       
  2245 			}
       
  2246 			$affinityGroup->StorageServices = $services;	
       
  2247 			
       
  2248 			return $affinityGroup;
       
  2249 		} else {
       
  2250 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2251 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2252 		}
       
  2253     }
       
  2254     
       
  2255     /**
       
  2256      * The List Locations operation lists all of the data center locations
       
  2257      * that are valid for your subscription.
       
  2258      * 
       
  2259      * @return array Array of Zend_Service_WindowsAzure_Management_LocationInstance
       
  2260      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  2261      */
       
  2262     public function listLocations()
       
  2263     {
       
  2264         $response = $this->_performRequest(self::OP_LOCATIONS);
       
  2265 
       
  2266     	if ($response->isSuccessful()) {
       
  2267 			$result = $this->_parseResponse($response);
       
  2268 			
       
  2269     		if (!$result->Location) {
       
  2270 				return array();
       
  2271 			}
       
  2272 		    if (count($result->Location) > 1) {
       
  2273     		    $xmlServices = $result->Location;
       
  2274     		} else {
       
  2275     		    $xmlServices = array($result->Location);
       
  2276     		}
       
  2277     		
       
  2278 			$services = array();
       
  2279 			if (!is_null($xmlServices)) {				
       
  2280 				
       
  2281 				for ($i = 0; $i < count($xmlServices); $i++) {
       
  2282 					$services[] = new Zend_Service_WindowsAzure_Management_LocationInstance(
       
  2283 					    (string)$xmlServices[$i]->Name
       
  2284 					);
       
  2285 				}
       
  2286 			}
       
  2287 			return $services;
       
  2288 		} else {
       
  2289 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2290 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2291 		}
       
  2292     }
       
  2293     
       
  2294     /**
       
  2295      * The List Operating Systems operation lists the versions of the guest operating system
       
  2296      * that are currently available in Windows Azure. The 2010-10-28 version of List Operating
       
  2297      * Systems also indicates what family an operating system version belongs to.
       
  2298      * Currently Windows Azure supports two operating system families: the Windows Azure guest
       
  2299      * operating system that is substantially compatible with Windows Server 2008 SP2,
       
  2300      * and the Windows Azure guest operating system that is substantially compatible with
       
  2301      * Windows Server 2008 R2.
       
  2302      * 
       
  2303      * @return array Array of Zend_Service_WindowsAzure_Management_OperatingSystemInstance
       
  2304      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  2305      */
       
  2306     public function listOperatingSystems()
       
  2307     {
       
  2308         $response = $this->_performRequest(self::OP_OPERATINGSYSTEMS);
       
  2309 
       
  2310     	if ($response->isSuccessful()) {
       
  2311 			$result = $this->_parseResponse($response);
       
  2312 			
       
  2313     		if (!$result->OperatingSystem) {
       
  2314 				return array();
       
  2315 			}
       
  2316 		    if (count($result->OperatingSystem) > 1) {
       
  2317     		    $xmlServices = $result->OperatingSystem;
       
  2318     		} else {
       
  2319     		    $xmlServices = array($result->OperatingSystem);
       
  2320     		}
       
  2321     		
       
  2322 			$services = array();
       
  2323 			if (!is_null($xmlServices)) {				
       
  2324 				
       
  2325 				for ($i = 0; $i < count($xmlServices); $i++) {
       
  2326 					$services[] = new Zend_Service_WindowsAzure_Management_OperatingSystemInstance(
       
  2327 					    (string)$xmlServices[$i]->Version,
       
  2328 					    (string)$xmlServices[$i]->Label,
       
  2329 					    ((string)$xmlServices[$i]->IsDefault == 'true'),
       
  2330 					    ((string)$xmlServices[$i]->IsActive == 'true'),
       
  2331 					    (string)$xmlServices[$i]->Family,
       
  2332 					    (string)$xmlServices[$i]->FamilyLabel
       
  2333 					);
       
  2334 				}
       
  2335 			}
       
  2336 			return $services;
       
  2337 		} else {
       
  2338 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2339 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2340 		}
       
  2341     }
       
  2342     
       
  2343     /**
       
  2344      * The List OS Families operation lists the guest operating system families
       
  2345      * available in Windows Azure, and also lists the operating system versions
       
  2346      * available for each family. Currently Windows Azure supports two operating
       
  2347      * system families: the Windows Azure guest operating system that is
       
  2348      * substantially compatible with Windows Server 2008 SP2, and the Windows
       
  2349      * Azure guest operating system that is substantially compatible with
       
  2350      * Windows Server 2008 R2.
       
  2351      * 
       
  2352      * @return array Array of Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance
       
  2353      * @throws Zend_Service_WindowsAzure_Management_Exception
       
  2354      */
       
  2355     public function listOperatingSystemFamilies()
       
  2356     {
       
  2357         $response = $this->_performRequest(self::OP_OPERATINGSYSTEMFAMILIES);
       
  2358 
       
  2359     	if ($response->isSuccessful()) {
       
  2360 			$result = $this->_parseResponse($response);
       
  2361 			
       
  2362     		if (!$result->OperatingSystemFamily) {
       
  2363 				return array();
       
  2364 			}
       
  2365 		    if (count($result->OperatingSystemFamily) > 1) {
       
  2366     		    $xmlServices = $result->OperatingSystemFamily;
       
  2367     		} else {
       
  2368     		    $xmlServices = array($result->OperatingSystemFamily);
       
  2369     		}
       
  2370     		
       
  2371 			$services = array();
       
  2372 			if (!is_null($xmlServices)) {				
       
  2373 				
       
  2374 				for ($i = 0; $i < count($xmlServices); $i++) {
       
  2375 					$services[] = new Zend_Service_WindowsAzure_Management_OperatingSystemFamilyInstance(
       
  2376 					    (string)$xmlServices[$i]->Name,
       
  2377 					    (string)$xmlServices[$i]->Label
       
  2378 					);
       
  2379 								
       
  2380 					if (count($xmlServices[$i]->OperatingSystems->OperatingSystem) > 1) {
       
  2381 		    		    $xmlOperatingSystems = $xmlServices[$i]->OperatingSystems->OperatingSystem;
       
  2382 		    		} else {
       
  2383 		    		    $xmlOperatingSystems = array($xmlServices[$i]->OperatingSystems->OperatingSystem);
       
  2384 		    		}
       
  2385 		    		
       
  2386 					$operatingSystems = array();
       
  2387 					if (!is_null($xmlOperatingSystems)) {				
       
  2388 						require_once 'Zend/Service/WindowsAzure/Management/OperatingSystemInstance.php';
       
  2389 						for ($i = 0; $i < count($xmlOperatingSystems); $i++) {
       
  2390 							$operatingSystems[] = new Zend_Service_WindowsAzure_Management_OperatingSystemInstance(
       
  2391 							    (string)$xmlOperatingSystems[$i]->Version,
       
  2392 							    (string)$xmlOperatingSystems[$i]->Label,
       
  2393 							    ((string)$xmlOperatingSystems[$i]->IsDefault == 'true'),
       
  2394 							    ((string)$xmlOperatingSystems[$i]->IsActive == 'true'),
       
  2395 							    (string)$xmlServices[$i]->Name,
       
  2396 							    (string)$xmlServices[$i]->Label
       
  2397 							);
       
  2398 						}
       
  2399 					}
       
  2400 					$services[ count($services) - 1 ]->OperatingSystems = $operatingSystems;
       
  2401 				}
       
  2402 			}
       
  2403 			return $services;
       
  2404 		} else {
       
  2405 			require_once 'Zend/Service/WindowsAzure/Management/Exception.php';
       
  2406 			throw new Zend_Service_WindowsAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
  2407 		}
       
  2408     }
       
  2409     
       
  2410     /**
       
  2411      * Clean configuration
       
  2412      * 
       
  2413      * @param string $configuration Configuration to clean.
       
  2414      * @return string
       
  2415      */
       
  2416     public function _cleanConfiguration($configuration) {
       
  2417     	$configuration = str_replace('?<?', '<?', $configuration);
       
  2418 		$configuration = str_replace("\r", "", $configuration);
       
  2419 		$configuration = str_replace("\n", "", $configuration);
       
  2420 		
       
  2421 		return $configuration;
       
  2422     }
       
  2423 }