Condividi tramite


Creare un account di archiviazione

 

Tramite l'operazione asincrona Create Storage Account viene creato un nuovo account di archiviazione in Microsoft Azure.

Richiesta

La richiesta di Create Storage Account può essere specificata come indicato di seguito. Sostituire <subscription-id> con l'ID sottoscrizione.

Metodo URI della richiesta
POST https://management.core.windows.net/<subscription-id>/services/storageservices

È necessario verificare che la richiesta eseguita al servizio di gestione sia sicura. Per ulteriori dettagli, vedere l'autenticazione di richieste di gestione del servizio.

Parametri URI

Nessuna.

Intestazioni della richiesta

La tabella seguente descrive le intestazioni della richiesta.

Intestazione della richiesta Descrizione
Content-Type Obbligatorio. Impostare questa intestazione su application/xml.
x-ms-version Obbligatorio. Specifica la versione dell'operazione da usare per questa richiesta. Il valore di questa intestazione deve essere impostato su 2011-06-01 o versione successiva. Per ulteriori informazioni sulle intestazioni di controllo delle versioni, vedere il controllo delle versioni di Service Management.

Corpo della richiesta

Il formato per il corpo della richiesta è il seguente:

<?xml version="1.0" encoding="utf-8"?> <CreateStorageServiceInput xmlns="https://schemas.microsoft.com/windowsazure"> <ServiceName>name-of-storage-account</ServiceName> <Description>description-of-storage-account</Description> <Label>base64-encoded-label</Label> <AffinityGroup>name-of-affinity-group</AffinityGroup> <Location>location-of-storage-account</Location> <GeoReplicationEnabled>geo-replication-indicator</GeoReplicationEnabled> <ExtendedProperties> <ExtendedProperty> <Name>property-name</Name> <Value>property-value</Value> </ExtendedProperty> </ExtendedProperties> <SecondaryReadEnabled>secondary-read-indicator</SecondaryReadEnabled> <AccountType>type-of-storage-account</AccountType> </CreateStorageServiceInput>  
  

Nella tabella indicata di seguito vengono descritti gli elementi del corpo della richiesta.

Nome elemento Descrizione
Service Name Obbligatorio. Nome dell'account di archiviazione univoco all'interno di Azure. I nomi degli account di archiviazione devono essere compresi tra 3 e 24 caratteri e usare solo numeri e lettere minuscole.

Corrisponde al nome del prefisso DNS e può essere usato per accedere a BLOB, code e tabelle nell'account di archiviazione.

Ad esempio: http://ServiceName.blob.core.windows.net/mycontainer/
Label Obbligatorio. Etichetta per l'account di archiviazione specificato come stringa con codifica Base 64. L'etichetta può contenere un massimo di 100 caratteri. L'etichetta può essere usata per identificare l'account di archiviazione per motivi di rilevamento.
Descrizione Facoltativa. Descrizione dell'account di archiviazione. La descrizione può contenere un massimo di 1024 caratteri.
Location Obbligatorio se AffinityGroup non viene specificato. Posizione in cui viene creato l'account di archiviazione.

È possibile includere un elemento Location o AffinityGroup nel corpo della richiesta, ma non entrambi. Per elencare le posizioni disponibili, usare l'operazione Elencare le posizioni.
AffinityGroup Obbligatorio se Location non viene specificato. Nome di un gruppo di affinità esistente nella sottoscrizione specificata.

È possibile includere un elemento Location o AffinityGroup nel corpo della richiesta, ma non entrambi. Per elencare li gruppi di affinità disponibili, usare l'operazione Elencare i gruppi di affinità.
GeoReplicationEnabled Facoltativa. Specifica se l'account di archiviazione viene creato con la replica geografica abilitata. Se l'elemento non è incluso nel corpo della richiesta, il valore predefinito è true. Se è impostato su true, i dati dell'account di archiviazione vengono replicati in più di una posizione geografica in modo da abilitare la resilienza in cado di perdita irreversibile di servizio.

L'elemento GeoReplicationEnabled è disponibile solo se si usa la versione 01.03.12 o una versione successiva e viene sostituito dall'elemento AccountType con la versione 2014-06-01 o una versione successiva.
Nome Facoltativa. Rappresenta il nome di una proprietà estesa dell'account di archiviazione. Ogni proprietà estesa deve contenere un nome e un valore definiti. È possibile avere un massimo di 50 proprietà estese coppie nome/valore.

La lunghezza massima dell'elemento Name è di 64 caratteri. Nel nome sono validi solo i caratteri alfanumerici e i caratteri di sottolineatura. Il nome deve iniziare con una lettera. Se si tenta di usare altri caratteri, di immettere un elemento Name che inizia con un carattere diverso da una lettera o di specificare un nome identico a quello di un'altra proprietà estesa appartenente allo stesso account di archiviazione, si verificherà un errore con codice di stato 400 (Richiesta non valida).

L'elemento Name è disponibile solo se si usa la versione 2012-03-01 o una versione successiva.
Valore Facoltativa. Rappresenta il valore di una proprietà estesa dell'account di archiviazione. Ogni proprietà estesa deve contenere un nome e un valore definiti. È possibile avere un massimo di 50 coppie nome/valore per le proprietà estese e il valore di ciascuna proprietà contiene un massimo di 255 caratteri.

L'elemento Value è disponibile solo se si usa la versione 2012-03-01 o una versione successiva.
SecondaryReadEnabled Facoltativa. Indica se è abilitata la lettura secondaria per l'account di archiviazione.

I valori possibili sono:

- true
- false

L'elemento SecondaryReadEnabled è disponibile solo se si usa la versione 2013-11-01 o una versione successiva e viene sostituito dall'elemento AccountType con la versione 2014-06-01 o una versione successiva.
AccountType Specifica se l'account supporta l'archiviazione con ridondanza locale, l'archiviazione con ridondanza geografica, l'archiviazione con ridondanza della zona o l'archiviazione con ridondanza geografica e accesso in lettura.

I valori possibili sono:

- Standard_LRS
- Standard_ZRS
- Standard_GRS
- Standard_RAGRS
- Premium_LRS

L'elemento AccountType è disponibile solo se si usa la versione 2014-06-01 o una versione successiva e sostituisce gli elementi SecondaryReadEnabled e GeoReplicationEnabled.

Il Premium_LRS elemento è disponibile solo utilizzando la versione 2014-10-01 o superiore. Note: Non è possibile modificare un account Standard_ZRS impostando un altro tipo di account successivamente e gli altri tipi di account non possono essere modificati in un account Standard_ZRS. Lo stesso vale per gli account Premium_LRS.

Risposta

Nella risposta sono inclusi un codice di stato HTTP, un set di intestazioni per la risposta e il corpo di una risposta.

Codice di stato

Un'operazione completata correttamente restituisce 200 (OK). Per informazioni sui codici di stato, vedere stato di gestione del servizio e i codici di errore.

Intestazioni della risposta

Nella risposta per questa operazione sono incluse le intestazioni riportate di seguito; inoltre, possono essere incluse intestazioni HTTP standard aggiuntive. Tutte le intestazioni standard sono conformi alla specifica del protocollo HTTP/1.1.

Intestazione della risposta Descrizione
x-ms-request-id Valore che identifica in modo univoco una richiesta eseguita nel servizio di gestione. Per un'operazione asincrona, è possibile chiamare Ottenere lo stato di operazione con il valore dell'intestazione per determinare se l'operazione è stata completata, ha avuto esito negativo o è ancora in corso.

Corpo della risposta

Nessuna.

Osservazioni

È possibile creare account di archiviazione a livello di programmazione con l'operazione Create Storage Account, fino ai limiti disponibili nella sottoscrizione. Per informazioni sui limiti correlati agli account di archiviazione, vedere Sottoscrizione di Azure e limiti dei servizi, quote e vincoli.

L'operazione restituisce immediatamente un ID di richiesta, mentre la creazione dell'account di archiviazione viene eseguita in modo asincrono da Azure, perché il provisioning di un nuovo account di archiviazione potrebbe richiedere alcuni minuti. Per verificare se l'operazione di creazione dell'account di archiviazione è stata completata, è possibile eseguire il polling dell'operazione Ottenere lo stato di operazione con l'ID richiesta. Viene restituito un corpo XML con un operazione elemento che contiene un stato elemento che avrà un valore di InProgress, Failed, o Succeeded, a seconda dello stato della creazione di account di archiviazione. Se si esegue il polling fino a quando lo stato non è Failed o Succeeded, l'elemento Operation conterrà un codice di stato nell'elemento StatusCode e le operazioni non riuscite conterranno altre informazioni sull'errore nell'elemento Error.

Le informazioni disponibili nell'articolo Obiettivi di scalabilità e prestazioni di Azure possono essere utili nella fase di pianificazione delle esigenze di archiviazione.

Esempio

Questo programma console di esempio crea un nuovo account di archiviazione impostando la descrizione, l'etichetta, la posizione e lo stato di replica geografica tramite l'operazione Create Storage Account, quindi esegue il polling dell'operazione Ottenere lo stato di operazione con l'ID richiesta restituito dall'operazione Create Storage Account fino a quando la chiamata ha esito positivo, negativo o non si verifica il timeout del polling. Infine, chiama Recupero delle proprietà dell'account di archiviazione per visualizzare le proprietà per il nuovo account di archiviazione. Per eseguire l'esempio, impostare il valore dell'intestazione x-ms-version nella stringa Version, l'identificatore di sottoscrizione in SubscriptionId, l'identificazione digitale del certificato di gestione in Thumbprinte ServiceName su un account di archiviazione univoco.

namespace Microsoft.WindowsAzure.ServiceManagementRESTAPI.Samples { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Xml; using System.Xml.Linq; public class Program { // Set these constants with your values to run the sample. private const string Version = "2011-12-01"; private const string Thumbprint = "management-certificate-thumbprint"; private const string SubscriptionId = "subscription-identifier"; private const string ServiceName = "unique-storage-account-name"; // This is the common namespace for all Service Management REST API XML data. private static XNamespace wa = "https://schemas.microsoft.com/windowsazure"; /// <summary> /// The operation status values from PollGetOperationStatus. /// </summary> private enum OperationStatus { InProgress, Failed, Succeeded, TimedOut } /// <summary> /// Gets or sets the certificate that matches the Thumbprint value. /// </summary> private static X509Certificate2 Certificate { get; set; } static void Main(string[] args) { try { Certificate = GetStoreCertificate(Thumbprint); // Create the new storage account with the following values: string description = "Description for my example storage account"; string label = "My example storage account label"; string location = "North Central US"; bool? enableGeoReplication = true; string requestId = CreateStorageAccount( ServiceName, description, label, null, location, enableGeoReplication); Console.WriteLine( "Called Create Storage Account operation: requestId {0}", requestId); // Loop on Get Operation Status for result of storage creation OperationResult result = PollGetOperationStatus( requestId, pollIntervalSeconds: 20, timeoutSeconds: 180); switch (result.Status) { case OperationStatus.TimedOut: Console.WriteLine( "Poll of Get Operation Status timed out: " + "Operation {0} is still in progress after {1} seconds.", requestId, (int)result.RunningTime.TotalSeconds); break; case OperationStatus.Failed: Console.WriteLine( "Failed: Operation {0} failed after " + "{1} seconds with status {2} ({3}) - {4}: {5}", requestId, (int)result.RunningTime.TotalSeconds, (int)result.StatusCode, result.StatusCode, result.Code, result.Message); break; case OperationStatus.Succeeded: Console.WriteLine( "Succeeded: Operation {0} completed " + "after {1} seconds with status {2} ({3})", requestId, (int)result.RunningTime.TotalSeconds, (int)result.StatusCode, result.StatusCode); break; } // Display the property values for the new storage account. // Convert the Label property to a readable value for display. XElement updatedProperties = GetStorageAccountProperties(ServiceName); XElement labelElement = updatedProperties.Descendants(wa + "Label").First(); labelElement.Value = labelElement.Value.FromBase64(); Console.WriteLine( "New Storage Account Properties for {0}:{1}{2}", ServiceName, Environment.NewLine, updatedProperties.ToString(SaveOptions.OmitDuplicateNamespaces)); } catch (Exception ex) { Console.WriteLine("Exception caught in Main:"); Console.WriteLine(ex.Message); } Console.Write("Press any key to continue:"); Console.ReadKey(); } /// <summary> /// Calls the Get Storage Account Properties operation in the Service /// Management REST API for the specified subscription and storage account /// name and returns the StorageService XML element from the response. /// </summary> /// <param name="serviceName">The name of the storage account.</param> /// <returns>The StorageService XML element from the response.</returns> private static XElement GetStorageAccountProperties( string serviceName) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "StorageService"); } /// <summary> /// Calls the Create Storage Account operation in the Service Management /// REST API for the specified subscription, storage account name, /// description, label, location or affinity group, and geo-replication /// enabled setting. /// </summary> /// <param name="serviceName">The name of the storage account to update.</param> /// <param name="description">The new description for the storage account.</param> /// <param name="label">The new label for the storage account.</param> /// <param name="affinityGroup">The affinity group name, or null to use a location.</param> /// <param name="location">The location name, or null to use an affinity group.</param> /// <param name="geoReplicationEnabled">The new geo-replication setting, if applicable. /// This optional parameter defaults to null.</param> /// <returns>The requestId for the operation.</returns> private static string CreateStorageAccount( string serviceName, string description, string label, string affinityGroup, string location, bool? geoReplicationEnabled = null) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId)); // Location and Affinity Group are mutually exclusive. // Use the location if it isn't null or empty. XElement locationOrAffinityGroup = String.IsNullOrEmpty(location) ? new XElement(wa + "AffinityGroup", affinityGroup) : new XElement(wa + "Location", location); // Create the request XML document XDocument requestBody = new XDocument( new XDeclaration("1.0", "UTF-8", "no"), new XElement( wa + "CreateStorageServiceInput", new XElement(wa + "ServiceName", serviceName), new XElement(wa + "Description", description), new XElement(wa + "Label", label.ToBase64()), locationOrAffinityGroup)); // Add the GeoReplicationEnabled element if the version supports it. if ((geoReplicationEnabled != null) && (String.CompareOrdinal(Version, "2011-12-01") >= 0)) { requestBody.Element( wa + "CreateStorageServiceInput").Add( new XElement( wa + "GeoReplicationEnabled", geoReplicationEnabled.ToString().ToLowerInvariant())); } XDocument responseBody; return InvokeRequest( uri, "POST", HttpStatusCode.Accepted, requestBody, out responseBody); } /// <summary> /// Calls the Get Operation Status operation in the Service /// Management REST API for the specified subscription and requestId /// and returns the Operation XML element from the response. /// </summary> /// <param name="requestId">The requestId of the operation to track.</param> /// <returns>The Operation XML element from the response.</returns> private static XElement GetOperationStatus( string requestId) { string uriFormat = "https://management.core.windows.net/{0}" + "/operations/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, requestId)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "Operation"); } /// <summary> /// The results from PollGetOperationStatus are passed in this struct. /// </summary> private struct OperationResult { // The status: InProgress, Failed, Succeeded, or TimedOut. public OperationStatus Status { get; set; } // The http status code of the requestId operation, if any. public HttpStatusCode StatusCode { get; set; } // The approximate running time for PollGetOperationStatus. public TimeSpan RunningTime { get; set; } // The error code for the failed operation. public string Code { get; set; } // The message for the failed operation. public string Message { get; set; } } /// <summary> /// Polls Get Operation Status for the operation specified by requestId /// every pollIntervalSeconds until timeoutSeconds have passed or the /// operation has returned a Failed or Succeeded status. /// </summary> /// <param name="requestId">The requestId of the operation to get status for.</param> /// <param name="pollIntervalSeconds">The interval between calls to Get Operation Status.</param> /// <param name="timeoutSeconds">The maximum number of seconds to poll.</param> /// <returns>An OperationResult structure with status or error information.</returns> private static OperationResult PollGetOperationStatus( string requestId, int pollIntervalSeconds, int timeoutSeconds) { OperationResult result = new OperationResult(); DateTime beginPollTime = DateTime.UtcNow; TimeSpan pollInterval = new TimeSpan(0, 0, pollIntervalSeconds); DateTime endPollTime = beginPollTime + new TimeSpan(0, 0, timeoutSeconds); bool done = false; while (!done) { XElement operation = GetOperationStatus(requestId); result.RunningTime = DateTime.UtcNow - beginPollTime; try { // Turn the Status string into an OperationStatus value result.Status = (OperationStatus)Enum.Parse( typeof(OperationStatus), operation.Element(wa + "Status").Value); } catch (Exception) { throw new ApplicationException(string.Format( "Get Operation Status {0} returned unexpected status: {1}{2}", requestId, Environment.NewLine, operation.ToString(SaveOptions.OmitDuplicateNamespaces))); } switch (result.Status) { case OperationStatus.InProgress: Console.WriteLine( "In progress for {0} seconds", (int)result.RunningTime.TotalSeconds); Thread.Sleep((int)pollInterval.TotalMilliseconds); break; case OperationStatus.Failed: result.StatusCode = (HttpStatusCode)Convert.ToInt32( operation.Element(wa + "HttpStatusCode").Value); XElement error = operation.Element(wa + "Error"); result.Code = error.Element(wa + "Code").Value; result.Message = error.Element(wa + "Message").Value; done = true; break; case OperationStatus.Succeeded: result.StatusCode = (HttpStatusCode)Convert.ToInt32( operation.Element(wa + "HttpStatusCode").Value); done = true; break; } if (!done && DateTime.UtcNow > endPollTime) { result.Status = OperationStatus.TimedOut; done = true; } } return result; } /// <summary> /// Gets the certificate matching the thumbprint from the local store. /// Throws an ArgumentException if a matching certificate is not found. /// </summary> /// <param name="thumbprint">The thumbprint of the certificate to find.</param> /// <returns>The certificate with the specified thumbprint.</returns> private static X509Certificate2 GetStoreCertificate(string thumbprint) { List<StoreLocation> locations = new List<StoreLocation> { StoreLocation.CurrentUser, StoreLocation.LocalMachine }; foreach (var location in locations) { X509Store store = new X509Store("My", location); try { store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certificates = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, false); if (certificates.Count == 1) { return certificates[0]; } } finally { store.Close(); } } throw new ArgumentException(string.Format( "A Certificate with thumbprint '{0}' could not be located.", thumbprint)); } /// <summary> /// A helper function to invoke a Service Management REST API operation. /// Throws an ApplicationException on unexpected status code results. /// </summary> /// <param name="uri">The URI of the operation to invoke using a web request.</param> /// <param name="method">The method of the web request, GET, PUT, POST, or DELETE.</param> /// <param name="expectedCode">The expected status code.</param> /// <param name="requestBody">The XML body to send with the web request. Use null to send no request body.</param> /// <param name="responseBody">The XML body returned by the request, if any.</param> /// <returns>The requestId returned by the operation.</returns> private static string InvokeRequest( Uri uri, string method, HttpStatusCode expectedCode, XDocument requestBody, out XDocument responseBody) { responseBody = null; string requestId = String.Empty; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri); request.Method = method; request.Headers.Add("x-ms-Version", Version); request.ClientCertificates.Add(Certificate); request.ContentType = "application/xml"; if (requestBody != null) { using (Stream requestStream = request.GetRequestStream()) { using (StreamWriter streamWriter = new StreamWriter( requestStream, System.Text.UTF8Encoding.UTF8)) { requestBody.Save(streamWriter, SaveOptions.DisableFormatting); } } } HttpWebResponse response; HttpStatusCode statusCode = HttpStatusCode.Unused; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { // GetResponse throws a WebException for 4XX and 5XX status codes response = (HttpWebResponse)ex.Response; } try { statusCode = response.StatusCode; if (response.ContentLength > 0) { using (XmlReader reader = XmlReader.Create(response.GetResponseStream())) { responseBody = XDocument.Load(reader); } } if (response.Headers != null) { requestId = response.Headers["x-ms-request-id"]; } } finally { response.Close(); } if (!statusCode.Equals(expectedCode)) { throw new ApplicationException(string.Format( "Call to {0} returned an error:{1}Status Code: {2} ({3}):{1}{4}", uri.ToString(), Environment.NewLine, (int)statusCode, statusCode, responseBody.ToString(SaveOptions.OmitDuplicateNamespaces))); } return requestId; } } /// <summary> /// Helpful extension methods for converting strings to and from Base-64. /// </summary> public static class StringExtensions { /// <summary> /// Converts a UTF-8 string to a Base-64 version of the string. /// </summary> /// <param name="s">The string to convert to Base-64.</param> /// <returns>The Base-64 converted string.</returns> public static string ToBase64(this string s) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s); return Convert.ToBase64String(bytes); } /// <summary> /// Converts a Base-64 encoded string to UTF-8. /// </summary> /// <param name="s">The string to convert from Base-64.</param> /// <returns>The converted UTF-8 string.</returns> public static string FromBase64(this string s) { byte[] bytes = Convert.FromBase64String(s); return System.Text.Encoding.UTF8.GetString(bytes); } } }  
  

Quando viene eseguito, il programma di esempio genera un output della console simile al seguente:

Called Create Storage Account operation: requestId 8ba8bd9cdc50472892a0b3cd3659b297 In progress for 0 seconds In progress for 20 seconds In progress for 41 seconds In progress for 61 seconds In progress for 82 seconds In progress for 103 seconds Succeeded: Operation 8ba8bd9cdc50472892a0b3cd3659b297 completed after 123 seconds with status 200 (OK) New Storage Account Properties for myexamplestorage1: <StorageService xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Url>https://management.core.windows.net/01234567-89ab-cdef-0123-456789abcdef/services/storageservices/myexamplestorage1</Url> <ServiceName>myexamplestorage1</ServiceName> <StorageServiceProperties> <Description>Description for my example storage account</Description> <Location>North Central US</Location> <Label>My example storage account label</Label> <Status>Created</Status> <Endpoints> <Endpoint>http://myexamplestorage1.blob.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.queue.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.table.core.windows.net/</Endpoint> </Endpoints> <GeoReplicationEnabled>true</GeoReplicationEnabled> <GeoPrimaryRegion>usnorth</GeoPrimaryRegion> <StatusOfPrimary>Available</StatusOfPrimary> <GeoSecondaryRegion>ussouth</GeoSecondaryRegion> <StatusOfSecondary>Available</StatusOfSecondary> </StorageServiceProperties> </StorageService> Press any key to continue: