使用Azure Batch Restful API创建azure batch pool,遇到异常
Create azure batch pool using Azure Batch Restful API, encounter exception
我正在尝试使用 RESTful API 创建池。我知道有用于批处理服务的 C# 库,但为了以编程方式指定子网 ID,我必须使用 RESTful API 来创建它,我在 this MSDN article.
我的Post 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"}
at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request)
at System.Net.WebClient.UploadString(Uri address, String method, String data)
at System.Net.WebClient.UploadString(String address, String method, String data)
at batchServer.Program.createPool(String poolId, String machineSize, String osFamily, String subnetId, String commandLine, Int32 numberOfMachine, List`1 resourceFiles) in C:\Users\fange\Downloads\ALMTest-master\batchServer\Program.cs:line 61
谁能帮帮我?
根据你提供的代码,我这边测试重现了这个问题。调试代码时,可以发现详细错误如下:
据我所知,一些常见的headers被认为是受限制的,受系统保护,不能在WebHeaderCollection
object中设置或更改,你可以按照这个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属性是互斥的,只能指定其中一个属性。如果两者均未指定,则批处理服务 returns 错误请求 (400)。因此,上述函数中的 jsonData 参数应如下所示:
"{\"id\":\"DotNetPool\",\"vmSize\":\"small\",\"cloudServiceConfiguration\":{\"osFamily\":\"4\"}}"
更新:
编码 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。
自 5.0.0 起,Azure Batch C# 客户端 SDK 能够为 Windows 基于云服务的实例加入虚拟网络。您不需要直接调用 REST 端点。
- Added support for joining a CloudPool to a virtual network on using the NetworkConfiguration property.
您可以在此处查看 5.0.0 的 ChangeLog:https://www.nuget.org/packages/Azure.Batch/5.0.0 但请使用最新版本。
我正在尝试使用 RESTful API 创建池。我知道有用于批处理服务的 C# 库,但为了以编程方式指定子网 ID,我必须使用 RESTful API 来创建它,我在 this MSDN article.
我的Post 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"}
at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request) at System.Net.WebClient.UploadString(Uri address, String method, String data)
at System.Net.WebClient.UploadString(String address, String method, String data) at batchServer.Program.createPool(String poolId, String machineSize, String osFamily, String subnetId, String commandLine, Int32 numberOfMachine, List`1 resourceFiles) in C:\Users\fange\Downloads\ALMTest-master\batchServer\Program.cs:line 61
谁能帮帮我?
根据你提供的代码,我这边测试重现了这个问题。调试代码时,可以发现详细错误如下:
据我所知,一些常见的headers被认为是受限制的,受系统保护,不能在WebHeaderCollection
object中设置或更改,你可以按照这个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属性是互斥的,只能指定其中一个属性。如果两者均未指定,则批处理服务 returns 错误请求 (400)。因此,上述函数中的 jsonData 参数应如下所示:
"{\"id\":\"DotNetPool\",\"vmSize\":\"small\",\"cloudServiceConfiguration\":{\"osFamily\":\"4\"}}"
更新:
编码 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。
自 5.0.0 起,Azure Batch C# 客户端 SDK 能够为 Windows 基于云服务的实例加入虚拟网络。您不需要直接调用 REST 端点。
- Added support for joining a CloudPool to a virtual network on using the NetworkConfiguration property.
您可以在此处查看 5.0.0 的 ChangeLog:https://www.nuget.org/packages/Azure.Batch/5.0.0 但请使用最新版本。