如何在Azure Data Factory v2中配置Webhook活动以执行Runbook?

时间:2019-10-31 00:37:12

标签: webhooks azure-data-factory-2 azure-runbook

我正在从ADF运行运行手册(PowerShell和图形)。我发现完成此任务的方法之一是使用webhooks。我将有并行和串行运行的运行手册(如果以前的运行手册存在依赖性)。

总体

  • 如果将平面文件拖放到Azure Blob存储中,则它将触发包含相应运行手册的管道。这部分正在工作。

  • Runbook的Webhook在ADF Webhook活动中使用。这就是我面临的问题。我不确定webhook活动的内容应该是什么?

经过一些研究,我能够找到一些需要在Webhook主体中添加(或以某种方式生成)的Callback uri的信息。我如何获得此回调uri?如果我没有添加适当的回调uri,则该活动将一直运行直到超时。我相信,当成功运行正在运行的Runbook时,应该是webhook活动完成,因此我们可以继续进行管道中的下一个webhook活动。我也尝试过网络活动,但这是同样的问题。

我现在正在使用的主体位于json下方。

{“ body”:{“ myMessage”:“ Sample”}}

我已引用:

https://vanishedgradient.com/2019/04/25/webhooks-with-azure-data-factory/

https://mrpaulandrew.com/2019/06/18/azure-data-factory-web-hook-vs-web-activity/

https://social.msdn.microsoft.com/Forums/en-US/2effcefb-e65b-4d5c-8b01-138c95126b79/in-azure-data-factory-v2-how-to-process-azure-analysis-service-cube?forum=AzureDataFactory

3 个答案:

答案 0 :(得分:3)

感谢链接,它们是有用的资源。我设法使它在管道中运行,该管道调用Runbook来调整天蓝色分析服务的大小。没有充分记录Runbook返回失败和成功信息。

这里有一些代码可以提供一些帮助,这是我从多个地方获取的,但从以下Microsoft页面上的未解决问题(https://github.com/MicrosoftDocs/azure-docs/issues/43897)中学到的很多:https://docs.microsoft.com/en-us/azure/data-factory/control-flow-webhook-activity

数据工厂Webhook活动传入一些“标头”,SourceHost是@pipeline()。DataFactory,而SourceProcess是@pipeline()。Pipeline。这样一来,我们可以进行一些检查,以确认运行手册是否正在由可接受的进程运行。

调用主体是我们需要的其他变量:

@json(concat('{"AnalysisServer":"', pipeline().parameters.AASName, '", "MinimumSKU":"', pipeline().parameters.SKU,'"}') )

您的Runbook需要WebhookData参数

param
(
    [Parameter (Mandatory=$false)]
    [object] $WebhookData
)

然后,您可以抓住所有需要的位,包括检查是否提供了callbackuri:

if ($WebhookData)
{

    # Split apart the WebhookData
    $WebhookName     =     $WebhookData.WebhookName
    $WebhookHeaders  =     $WebhookData.RequestHeader
    $WebhookBody     =     $WebhookData.RequestBody | Convertfrom-Json
    $WebhookADF      =     $WebhookHeaders.SourceHost
    $WebhookPipeline =     $WebhookHeaders.SourceProcess

Write-Output -InputObject ('Runbook started through webhook {0} called by {1} on {2}.' -f $WebhookName, $WebhookPipeline, $WebhookADF)

# if there's a callBackURI then we've been called by something that is waiting for a response
If ($WebhookBody.callBackUri)
{
    $WebhookCallbackURI =  $WebhookBody.callBackUri
}

...
}

变量$ WebHookHeaders:@{Connection=Keep-Alive; Expect=100-continue; Host=sXXevents.azure-automation.net; SourceHost=**MYDATAFACTORYNAME**; SourceProcess=**MYPIPELINENAME**; x-ms-request-id=**UNIQUEIDENTIFIER**}

然后您可以从json正文中获取信息:$AzureAnalysisServerName = $WebHookBody.AnalysisServer

将错误/故障传递回您的运行簿相对容易,请注意,我将成功/更新消息放入$ Message中,并且只有在出现错误时才在$ ErrorMessage中包含内容:

$ErrorMessage = "Failed to do stuff I wanted" 

if ($ErrorMessage) 
{

    $Output = [ordered]@{ output= @{
        AzureAnalysisServerResize = "Failed" }
        error = @{
            ErrorCode = "ResizeError"
            Message = $ErrorMessage
        }
        statusCode = "500"
    }
} else {
    $Output = [ordered]@{ 
        output= @{ 
            "AzureAnalysisServerResize" = "Success"
            "message" = $Outputmessage 
        }
        statusCode = "200"
    }
}

$OutputJson = $Output | ConvertTo-Json -Depth 10

# if we have a callbackuri let the ADF Webhook activity know that the script is complete 
# Otherwise it waits until its timeout
If ($WebhookCallBackURI)
{
    $WebhookCallbackHeaders = @{
        "Content-Type"="application/json"
    }
    Invoke-WebRequest -UseBasicParsing -Uri $WebhookCallBackURI -Method Post -Body $OutputJson -Header $WebhookCallbackHeaders
}

然后我用另一个else结束if($ WebhookData){调用,说如果不从webhook调用,则运行本不应该运行:

} else {
    Write-Error -Message 'Runbook was not started from Webhook' -ErrorAction stop
}

传回错误消息非常容易,传回成功消息很痛苦,但是上面的方法似乎可行,在我的数据工厂管道中,我可以访问结果。

Output
{
    "message": "Analysis Server MYSERVERNAME which is SKU XX is already at or above required SKU XX.",
    "AzureAnalysisServerResize": "Success"
}

请注意,使用Invoke-WebRequest时,一些在线示例未指定-UseBasicParsing,但由于运行本手册所抱怨,我们不得不这样做:Invoke-WebRequest:由于Internet Explorer引擎不可用或Internet无法解析响应内容Explorer的首次启动配置尚未完成。

答案 1 :(得分:0)

我不确定这是否是最佳实践,但是我在Powershell Workflow Runbook中有某些工作。

如果Runbook定义了Webhook,则可以使用webhookdata参数。您的请求主体必须采用JSON格式,然后$ WebhookData参数将其选中。例如,假设您在webhook活动中的“身体”如下所示:

{“ MyParam”:1,“ MyOtherParam”:“ Hello”}

在运行本中,您可以通过以下方式选择参数:

Param([object]$WebhookData)

if($WebhookData){
    $parameters=(ConvertFrom-Json -InputObject $WebhookData.RequestBody)
    if($parameters.MyParam) {$ParamOne = $parameters.MyParam} 
    if($parameters.MyOtherParam) {$ParamTwo = $parameters.MyOtherParam} 
}

您的运行手册$ ParamOne和$ ParamTwo中的变量是从已解析的JSON Body字符串填充的。数据工厂会自动将callBackUri附加到Body字符串。您无需创建它。

您必须使用$ WebhookData名称。这是一个已定义的属性。

我希望这会有所帮助。

答案 2 :(得分:0)

致歉。几个月前,我已经找到了完整的解决方案。感谢Nick和Sara添加作品。我使用了类似的代码作为返回代码。我们使用的图形化运行手册允许进行有限的更改,因此我只在运行手册的末尾添加了返回代码(Powershell),几乎没有影响。我插入了以下代码:

if ($WebhookData)
{
    Write-Output $WebhookData
    $parameters = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
    if ($parameters.callBackUri)
    {
        $callbackuri = $parameters.callBackUri
    }
}


if ($callbackuri)
{
    Invoke-WebRequest -Uri $callbackuri -UseBasicParsing -Method POST
}

Write-Output $callbackuri

此后,我使用运行手册中的“输入和输出”按钮添加了输入参数。我将输入参数命名为“ WebhookData”,并键入“ Object”。输入参数的名称区分大小写,并且应与Powershell代码中使用的参数匹配。

这解决了我的问题。当从ADF管道调用该Runbook时开始,并且仅在由Webhook调用的基础Runbook完成时才移至下一个管道。