2016-08-30 10 views
0

Я пытаюсь создать пул с использованием API RESTful. Я знаю, что есть библиотека C# для пакетного обслуживания, но для того, чтобы программировать определение идентификатора подсети, я должен использовать RESTful API для создания его, о котором я читал в this MSDN article.Создать лазурный пакетный пул с использованием Azure Batch Restful API, встретить исключение

Мои сообщения URI следовать формату

https://{account-name}.{region-id}.batch.azure.com/pools?api-version={api-version}

Код

using (var client = new WebClient()) 
{ 
    client.Headers[HttpRequestHeader.ContentType] = "application/json"; 
    client.Headers[HttpRequestHeader.Authorization] = "SharedKey <AccountName>:<Signature>"; 
    client.Headers[HttpRequestHeader.Date] = DateTime.UtcNow.ToString(); 
    try 
    { 
     result = client.UploadString(baseURI, "POST", json); 
    } 
    catch(Exception ex) 
    { 
     Console.WriteLine(ex.StackTrace); 
    } 
    Console.WriteLine(result); 
} 

Я послал JSON: {"Id":"DotNetPool","vmSize":"small"}

в System.Net.WebClient.UploadDataInternal (Uri адрес , Метод String, данные байт [], WebRequest & запрос) в System.Net.WebClient.UploadString (адрес Uri, метод String, данные String)
at System.Net.WebClient.UploadString (адрес строки, метод String, данные String) at batchServer.Program.createPool (String) poolId, String machineSize, String osFamily, String subnetId, String CommandLine, Int32 numberOfMachine, List`1 resourceFiles) в C: \ Users \ fange \ Downloads \ ALMTest-мастер \ batchServer \ Program.cs: линия 61

Может кто-нибудь мне помочь?

+0

Вы разрешили эту проблему? Любые обновления? –

ответ

2

На основании кода, который вы предоставили, я проверил на своей стороне и воспроизвел эту проблему. При отладке кода, вы можете найти подробную ошибку следующим образом:

Насколько я знаю, некоторые общие заголовки считаются ограничены и защищены системой и не могут быть установлены или изменены в WebHeaderCollection объект, вы можете следить за этим tutorial.

Простым способом я рекомендую вам использовать HttpWebRequest вместо WebClient для достижения вашей цели. Вот мой тестовый код для создания пула с использованием RESTful API.

public static void CreatePoolViaRestAPI(string baseUrl, string batchAccountName, string batchAccountKey,string jsonData) 
{ 
    string verb = "POST"; 
    string apiVersion= "2016-07-01.3.1"; 
    string ocpDate= DateTime.UtcNow.ToString("R"); 
    string contentType = "application/json; odata=minimalmetadata; charset=utf-8"; 
    string reqUrl = string.Format("{0}/pools?api-version={1}", baseUrl, apiVersion); 

    //construct the request 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(reqUrl); 
    request.Method = verb; 
    //Set ContentType 
    request.ContentType = contentType; 
    //Set ocp-date 
    request.Headers.Add("ocp-date", ocpDate); 
    var buffer = Encoding.UTF8.GetBytes(jsonData); 
    request.ContentLength = buffer.Length; 

    #region generate the signature 
    string CanonicalizedHeaders = string.Format("ocp-date:{0}", ocpDate); 
    string CanonicalizedResource = string.Format("/{0}/pools\napi-version:{1}", batchAccountName, apiVersion); 
    string stringToSign = string.Format("{0}\n\n\n{1}\n\n{2}\n\n\n\n\n\n\n{3}\n{4}", 
     verb, 
     buffer.Length, 
     contentType, 
     CanonicalizedHeaders, CanonicalizedResource); 
    //encode the stringToSign 
    string signature = EncodeSignStringForSharedKey(stringToSign, batchAccountKey); 
    #endregion 

    //Set Authorization header 
    request.Headers.Add("Authorization", string.Format("SharedKey {0}:{1}", batchAccountName, signature)); 
    using (var rs = request.GetRequestStream()) 
    { 
     rs.Write(buffer, 0, buffer.Length); 
    } 

    //send the request and get response 
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
    { 
     Console.WriteLine("Response status code:{0}", response.StatusCode); 
    } 
} 

Примечание: cloudServiceConfiguration и свойства virtualMachineConfiguration являются взаимоисключающими, и только могут быть определены одним из свойств. Если ни один из них не указан, пакетная служба возвращает Bad Request (400). Поэтому параметр jsonData в функции выше должна выглядеть следующим образом:

"{\"id\":\"DotNetPool\",\"vmSize\":\"small\",\"cloudServiceConfiguration\":{\"osFamily\":\"4\"}}" 

UPDATE:

Способ кодирования stringToSign будет выглядеть следующим образом:

public string EncodeSignStringForSharedKey(string stringToSign, string accountKey) 
{ 
    HMACSHA256 h = new HMACSHA256(Convert.FromBase64String(accountKey)); 
    var byteArray = h.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)); 
    string signature = Convert.ToBase64String(byteArray); 
    return signature; 
} 

Детали вы может следовать Authentication via Shared Key.

+0

Где ваша функция '' 'EncodeSignStringForSharedKey' 'существует? – spevilgenius

+0

Я только что обновил свой ответ с помощью фрагмента кода, вы можете обратиться к нему. –

1

Пакет клиента Azure Batch C# клиента от 5.0.0 имеет возможность объединения виртуальной сети для экземпляров на базе Windows Cloud Service. Вам не нужно напрямую вызывать конечную точку REST.

- Added support for joining a CloudPool to a virtual network on using the NetworkConfiguration property.

Вы можете просмотреть список изменений 5.0.0 здесь: https://www.nuget.org/packages/Azure.Batch/5.0.0 но, пожалуйста, используйте последнюю версию.