因此,我正在制作一些 Azure持久函数的原型,以尝试了解它们是否适合我们内部API系统的建议解决方案。
基于示例,我创建了一个 Orchestrator客户端(HelloOrchestratorClient.cs
),它可以响应HttpTrigger
。该客户端从原始请求中提取了一些信息,然后继续执行 Orchestrator函数(HelloOrchestrator.cs
),传入了一些提取的信息:
[FunctionName("HttpSyncStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, methods: "get", Route = "orchestrators/{functionName}/wait")]
HttpRequestMessage req,
[OrchestrationClient] DurableOrchestrationClient starter,
string functionName,
ILogger log)
{
HttpReq originalRequest = new HttpReq() {
DeveloperId = GetDevKey(req,apiHeaderKey),
QueryString = req.RequestUri.Query,
APIName = GetQueryStringValue(req,APIName),
APIVersion = GetQueryStringValue(req,APIVersion)
};
string instanceId = await starter.StartNewAsync(functionName, originalRequest);
TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
req,
instanceId,
timeout,
retryInterval);
}
暂时HelloOrchestrator.cs
只是使用我们的一个内部API调用并返回一个JsonProduct
负载(使用{{1},简单的POCO描述了标题), }命名为ActivityTigger
来进行API调用。
HelloOrchestrator.APICall
侧注:该计划是,如果我能使它正常工作,那就是将一堆进程散开到不同的API,然后再次散开,合并JSON有效负载,然后将其返回到发起人。
因此,当我的 [FunctionName("E1_JsonProduct")]
public static async Task<List<JsonProduct>> Run(
[OrchestrationTrigger] DurableOrchestrationContextBase context,
ILogger log)
{
List<JsonProduct> output = new List<JsonProduct>();
HttpReq r = context.GetInput<HttpReq>();
if(r != null)
{
if(r.DeveloperId == null)
{
return output;
}
output.Add(await context.CallActivityAsync<JsonProduct>("E1_CallAPI",r));
return output;
}
return output;
}
[FunctionName("E1_CallAPI")]
public async static Task<JsonProduct> APICall([ActivityTrigger] HttpReq req,
ILogger log)
{
JsonProduct products = null;
string u = $"{baseAddress}{req.APIVersion}/{req.APIName}{req.QueryString}";
var request = new HttpRequestMessage(HttpMethod.Get, u);
request.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json")
);
request.Headers.Add("x-apikey",req.DeveloperId);
log.LogInformation($"URL calling = '{request.RequestUri.AbsoluteUri}'.");
HttpResponseMessage response = await client.SendAsync(request);
// return await response.Content.ReadAsStringAsync();
if(response.IsSuccessStatusCode)
{
var formatter = new JsonMediaTypeFormatter
{
SerializerSettings = HelloProj.CosmosDB.Models.Products.Converter.Settings
};
products = await response.Content.ReadAsAsync<JsonProduct>(new [] {formatter});
}
return products;
}
从List<JsonProduct>
返回时,我收到了在此Gist上找到的以下HelloOrchestrator.Run
(大堆栈跟踪),并且我收到了 Orchestrator客户端的> 500响应。
以下证明返回的NullReferenceException
在运行时确实有一个对象:
是否可能由于output
的复杂性(再次找到模型类here)?我问,因为当我将我的 Orchestrator函数换成更简单的模型结构时,我 不 收到500,我收到了JSON有效载荷。
此示例显示了简单协调器函数 JsonProduct
,返回了一个简单的HelloOrchestrator.cs
(Gist for model)平面对象,该对象没有错误:
TestToDo.cs
如果您需要我的完整原型项目,可以在这里找到它们:
运行它时,请在Postman之类的文件中使用以下内容(在F5加载后):
运行它时,请在Postman之类的东西中使用以下命令(在F5加载后):
http://localhost:7071/api/orchestrators/E1_Todo/wait?timeout=20&retryInterval=0.25
答案 0 :(得分:1)
看看您发布的调用堆栈,NullReferenceException
似乎是DurableOrchestrationClient
类中的错误。查看代码(可以找到here)似乎是有可能的,如果无法正确解析您正在使用的查询字符串,则可以使用null-ref。
您提到您正在使用以下URL进行测试:
我想知道最后两个字符(&N
)是否是问题的根源。是否可以对&
进行编码或将其完全删除以找出问题所在?
无论哪种方式,如果您可以在此处记录问题,那就太好了:https://github.com/Azure/azure-functions-durable-extension/issues