2016-08-30 2 views
0

RESTful API를 사용하여 풀을 만들려고합니다. 배치 서비스에 대한 C# 라이브러리가 있지만 프로그래밍 방식으로 서브넷 ID를 지정하려면 RESTful API를 사용하여 내가 작성한 this MSDN article을 작성해야합니다. {"Id":"DotNetPool","vmSize":"small"}Azure 배치 API를 사용하여 하늘 일괄 처리 풀 만들기, 예외 발생

System.Net.WebClient.UploadDataInternal에서 (열린 우리당 주소 :

내 포스트 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

에 따라 , String 메서드, Byte [] 데이터, WebRequest & 요청) at System.Net.WebClient.UploadString (Uri 주소, String 메서드, 문자열 데이터)
at System.Net.WebClient.UploadString (문자열 주소, 문자열 메서드, 문자열 데이터) at batchServer.Program.createPool (String C에서 poolId, 문자열 machineSize, 문자열 osFamily, 문자열 subnetId, 문자열 명령 행, INT32 numberOfMachine, List`1 resourceFiles) : batchServer \ Program.cs \ \ 사용자 \ fange \ 다운로드 \ ALMTest 마스터 : 라인 61

누구든지 나를 도울 수 있습니까?

+0

이 문제를 해결 했습니까? 모든 업데이트? –

답변

2

제공 한 코드를 기반으로 테스트를 해본 결과이 문제가 재현되었습니다. 코드를 디버깅 할 때 다음과 같이 자세한 오류를 찾을 수 :

를 지금까지 내가, 몇 가지 일반적인 헤더가 제한 간주됩니다 알고 시스템에 의해 보호하고, 설정 또는 변경할 수 없습니다로 WebHeaderCollection 개체 일 경우이 tutorial을 따를 수 있습니다.

간단하게 말해서 목적을 달성하기 위해 WebClient 대신 HttpWebRequest을 사용할 것을 권장합니다. 다음은 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 속성은 상호 배타적 만 속성 중 하나가 지정 될 수 있습니다. 둘 다 지정되지 않으면 배치 서비스는 잘못된 요청 (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

5.0.0 버전의 Azure Batch C# Client SDK에는 Windows 클라우드 서비스 기반 인스턴스 용 가상 네트워크에 참가할 수있는 기능이 있습니다. REST Endpoint를 직접 호출 할 필요는 없습니다.

- 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하지만 최신 버전을 사용하십시오.