(0) exportieren Drucken
Alle erweitern

Vorgangsstatus abrufen

Letzte Aktualisierung: September 2014

Durch den Vorgang Get Operation Status wird der Fortschritt des angegebenen Vorgangs zurückgegeben. Nachdem Sie einen asynchronen Vorgang aufgerufen haben, können Sie Get Operation Status aufrufen, um zu bestimmen, ob der Vorgang erfolgreich war, fehlgeschlagen ist oder noch ausgeführt wird.

Die Get Operation Status-Anforderung kann wie folgt angegeben werden. Ersetzen Sie <subscription-id> durch die Abonnement-ID und <request-id> durch die Anforderungs-ID, die in der Antwort zurückgegeben wurde.

 

Methode Anforderungs-URI

GET

https://management.core.windows.net/<subscription-id>/operations/<request-id>

Sie müssen sicherstellen, dass die an den Verwaltungsdienst gestellte Anforderung sicher ist. Zusätzliche Informationen finden Sie im Thema Authentifizieren von Dienstverwaltungsanforderungen.

Keiner.

In der folgenden Tabelle werden die Anforderungsheader beschrieben.

 

Anforderungsheader Beschreibung

x-ms-version

Erforderlich. Gibt die Version des für die Anforderung zu verwendenden Vorgangs an. Dieser Header sollte auf 01.10.2009 oder höher festgelegt werden. Weitere Informationen zu den Versionsangaben in den Headern finden Sie unter Dienstverwaltungs-Versionsverwaltung.

Die Antwort enthält den HTTP-Statuscode, einen Satz von Antwortheadern und einen Antworttext.

Bei einem erfolgreichen Vorgang wird der Statuscode 200 (OK) zurückgegeben. Weitere Informationen zu Statuscodes finden Sie unter Dienstverwaltungsstatus und Fehlercodes.

Die Antwort für diesen Vorgang umfasst die folgenden Header. Die Antwort kann außerdem weitere HTTP-Standardheader enthalten. Alle Standardheader entsprechen der HTTP/1.1-Protokollspezifikation.

 

Antwortheader Beschreibung

x-ms-request-id

Ein Wert, der eine für den Verwaltungsdienst ausgeführte Anforderung eindeutig identifiziert.

Der Antworttext enthält den Status des angegebenen asynchronen Vorgangs und lässt erkennen, ob er erfolgreich war, ausgeführt wird oder fehlgeschlagen ist. Dieser Status weicht von dem HTTP-Statuscode ab, der für den Vorgang Get Operation Status selbst zurückgegeben wird.

Wenn der asynchrone Vorgang erfolgreich war, enthält der Antworttext den HTTP-Statuscode für die erfolgreiche Anforderung.

Wenn der asynchrone Vorgang fehlgeschlagen ist, enthält der Antworttext den HTTP-Statuscode für die fehlerhafte Anforderung sowie Informationen zum Fehler.


<?xml version="1.0" encoding="utf-8"?>
  <Operation xmlns="http://schemas.microsoft.com/windowsazure">
    <ID>request-id</ID>
    <Status>InProgress|Succeeded|Failed</Status>
    <!--Response includes HTTP status code only if the operation succeeded or failed -->
    <HttpStatusCode>http-status-code-for-asynchronous-operation</HttpStatusCode>
    <!--Response includes additional error information only if the operation failed -->
    <Error>
      <Code>error-code</Code>
      <Message>error-message</Message>
    </Error>
  </Operation>

In der folgenden Tabelle werden die Elemente im Antworttext beschrieben.

 

Elementname Beschreibung

ID

Gibt die Anforderungs-ID der asynchronen Anforderung an. Dieser Wert wird im Antwortheader x-ms-request-id der asynchronen Anforderung zurückgegeben.

Status

Gibt den Status der asynchronen Anforderung an.

Folgende Werte sind möglich:

  • InProgress

  • Succeeded

  • Failed

HttpStatusCode

Gibt den HTTP-Statuscode für die asynchrone Anforderung an.

Code

Gibt den Fehlercode des Verwaltungsdiensts an, der zurückgegeben wird, wenn die asynchrone Anforderung fehlgeschlagen ist. Unter Dienstverwaltungsstatus und Fehlercodes finden Sie Informationen zu den möglichen Fehlercodes, die vom Dienst zurückgegeben werden.

Message

Gibt die Fehlermeldung des Verwaltungsdiensts an, die zurückgegeben wird, wenn die asynchrone Anforderung fehlgeschlagen ist.

Dienstverwaltungsvorgänge, für deren Abschluss eine umfangreiche Verarbeitung erforderlich ist, werden mit einem asynchronen Muster implementiert. Alle erfolgreichen Dienstverwaltungs-REST-API-Vorgangsanforderungen geben eine eindeutige Anforderungs-ID zurück, die zum Bestimmen des Endstatus eines Vorgangs verwendet werden kann. Dies geschieht, indem Get Operation Status mit der Anforderungs-ID abgerufen wird, bis der Vorgang erfolgreich war oder fehlschlägt. Eine asynchrone Vorgangsanforderung der Dienstverwaltung wird schnell zurückgegeben. Eine Fehlerantwort auf die asynchrone Vorgangsanforderung gibt an, dass die Anforderung nicht erfolgreich war und kein asynchroner Vorgang aussteht. Eine Vorgangsanforderung gibt einen Statuscode 202 (Akzeptiert) zurück, um anzugeben, dass die Anforderung erfolgreich war und aussteht. Durch den Vorgang Get Operation Status wird ein Fehlerstatuscode und ein Fehlerantworttext zurückgegeben, wenn der Aufruf von Get Operation Status nicht erfolgreich war, beispielsweise wenn die Anforderungs-ID keiner tatsächlichen Dienstverwaltungs-Vorgangsanforderung entspricht, die für das Abonnement ausgeführt wird. Ein Statuscode 200 (OK) bedeutet, dass der Aufruf von Get Operation Status erfolgreich war, und der durch den ID-Parameter angegebene Status des Vorgangs wird im zurückgegebenen Antworttext aufgezeichnet. Sie müssen den Antworttext auf den Status des asynchronen Vorgangs überprüfen. Das Operation-Element oder der Antworttext enthält einen Status-Elementwert, der den aktuellen Status des ausstehenden Vorgangs darstellt, der InProgress, Failed oder Succeeded lauten kann. Setzen Sie das Abrufen von Get Operation Status fort, solange das Status-Element den Status InProgress aufweist. Wenn das Status-Element den Wert Succeeded oder Failed aufweist, enthält das Operation-Element auch ein HttpStatusCode-Element, das den Statuscode für den abgeschlossenen asynchronen Vorgang enthält. Wenn das Status-Element Failed aufweist, enthält das Operation-Element ein Error-Element mit Code- und Message-Elementen, die weitere Details zum Fehler des asynchronen Vorgangs angeben.

Dieses beispielhafte Konsolenprogramm erstellt ein neues Speicherkonto, wobei die Beschreibung, die Bezeichnung und der Speicherort mithilfe des Vorgangs Speicherkonto erstellen festgelegt werden, und dann der Vorgang Get Operation Status mit der Anforderungs-ID abgefragt wird, die durch den Vorgang Speicherkonto erstellen zurückgegeben wurde, bis der Aufruf erfolgreich war oder fehlgeschlagen ist oder beim Abruf ein Timeout aufgetreten ist. Schließlich wird Speicherkonteneigenschaften abrufen aufgerufen, um die Eigenschaften für das neue Speicherkonto anzuzeigen. Legen Sie den Wert für den Header x-ms-version in der Zeichenfolge Version fest, den Abonnementbezeichner unter SubscriptionId, Ihren Verwaltungszertifikatfingerabdruck unter Thumbprint, und legen Sie ServiceName auf einen eindeutigen Speicherkontonamen fest, um das Beispiel auszuführen.

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-10-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 = "http://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 { getset; }
 
        static void Main(string[] args)
        {
            try
            {
                Certificate = GetCertificate(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";
                string requestId = CreateStorageAccount(
                    ServiceName, 
                    description, 
                    label, 
                    null, 
                    location);
                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, nullout 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, and location or affinity group.
        /// </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>
        /// <returns>The requestId for the operation.</returns>
        private static string CreateStorageAccount(
            string serviceName,
            string description,
            string label,
            string affinityGroup,
            string location)
        {
            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));
 
            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, nullout 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 { getset; }
 
            // The http status code of the requestId operation, if any.
            public HttpStatusCode StatusCode { getset; }
 
            // The approximate running time for PollGetOperationStatus.
            public TimeSpan RunningTime { getset; }
 
            // The error code for the failed operation.
            public string Code { getset; }
 
            // The message for the failed operation.
            public string Message { getset; }
        }
 
        /// <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 GetCertificate(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);
        }
    }
}

Dieses Beispielprogramm erzeugt bei der Ausführung eine Konsolenausgabe, die dem folgenden Beispiel ähnelt:

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="http://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>
  </StorageServiceProperties>
</StorageService>
Press any key to continue:

Anzeigen:
© 2014 Microsoft