From 928f2742bc7a9f8993a69e1776a5ed14823e1377 Mon Sep 17 00:00:00 2001 From: NandanHegde15 <67547199+NandanHegde15@users.noreply.github.com> Date: Mon, 14 Nov 2022 12:47:26 +0530 Subject: [PATCH 1/2] Create manifest.json --- .../manifest.json | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 templates/Cross Tenant Power BI Entity Refresh/manifest.json diff --git a/templates/Cross Tenant Power BI Entity Refresh/manifest.json b/templates/Cross Tenant Power BI Entity Refresh/manifest.json new file mode 100644 index 00000000..b64619f5 --- /dev/null +++ b/templates/Cross Tenant Power BI Entity Refresh/manifest.json @@ -0,0 +1,30 @@ +{ + "name":"PowerBIEntityProcessingViaServicePrincipal", + "description":"This pipeline refreshes datasets/dataflows via Service Principal and the EntityType parameter can be either dataset or dataflow", + "image":"WebTriggerPowerBIRefreshUntilStatusUntilPowerBIRefreshesActivitiesACT_Cmn_WaitFor3...GetRefreshDetails+If ConditionIfRefreshFailedTrueThrowErrorOnFailure+False+", + "icons":[ + "WebActivity", + "Until", + "IfCondition" + ], + "requires":{ + "linkedservices":{ + "LS_AKV":{ + "supportTypes":[ + "AzureKeyVault" + ] + } + } + }, + "contributorType": "Community", + "author":"Nandan Hegde", + "annotations":[ + + ], + "services":[ + "Power BI" + ], + "categories":[ + + ] +} From 4539e2a1ded3242fd71ae3616eda7aea73d99174 Mon Sep 17 00:00:00 2001 From: NandanHegde15 <67547199+NandanHegde15@users.noreply.github.com> Date: Mon, 14 Nov 2022 12:53:56 +0530 Subject: [PATCH 2/2] Create PowerBIEntityProcessingViaServicePrincipal.json --- ...BIEntityProcessingViaServicePrincipal.json | 257 ++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 templates/Cross Tenant Power BI Entity Refresh/PowerBIEntityProcessingViaServicePrincipal.json diff --git a/templates/Cross Tenant Power BI Entity Refresh/PowerBIEntityProcessingViaServicePrincipal.json b/templates/Cross Tenant Power BI Entity Refresh/PowerBIEntityProcessingViaServicePrincipal.json new file mode 100644 index 00000000..46edf3b3 --- /dev/null +++ b/templates/Cross Tenant Power BI Entity Refresh/PowerBIEntityProcessingViaServicePrincipal.json @@ -0,0 +1,257 @@ +{ + "$schema":"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion":"1.0.0.0", + "parameters":{ + "factoryName":{ + "type":"string", + "metadata":"Data Factory name" + }, + "LS_AKV":{ + "type":"string" + } + }, + "variables":{ + "factoryId":"[concat('Microsoft.DataFactory/factories/', parameters('factoryName'))]" + }, + "resources":[ + { + "name":"[concat(parameters('factoryName'), '/PowerBIEntityProcessingViaServicePrincipal')]", + "type":"Microsoft.DataFactory/factories/pipelines", + "apiVersion":"2018-06-01", + "properties":{ + "description":"This pipeline refreshes datasets/dataflows via Service Principal and the EntityType parameter can be either dataset or dataflow", + "activities":[ + { + "name":"TriggerPowerBIRefresh", + "description":"This activity would start the PowerBI Dataset / Dataflow refresh", + "type":"WebActivity", + "dependsOn":[ + + ], + "policy":{ + "timeout":"7.00:00:00", + "retry":0, + "retryIntervalInSeconds":30, + "secureOutput":false, + "secureInput":false + }, + "userProperties":[ + + ], + "typeProperties":{ + "url":{ + "value":"@concat('https://api.powerbi.com/v1.0/myorg/groups/',pipeline().parameters.WorkspaceId,if(equals(toUpper(pipeline().parameters.EntityType),'DATASET'),'/datasets/','/dataflows/'),pipeline().parameters.EntityId,'/refreshes')", + "type":"Expression" + }, + "method":"POST", + "headers":{ + + }, + "body":{ + "notifyOption":"NoNotification" + }, + "authentication":{ + "type":"ServicePrincipal", + "userTenant":{ + "value":"@pipeline().parameters.TenantId", + "type":"Expression" + }, + "username":{ + "value":"@pipeline().parameters.ClientId", + "type":"Expression" + }, + "resource":"https://analysis.windows.net/powerbi/api", + "password":{ + "type":"AzureKeyVaultSecret", + "store":{ + "referenceName":"[parameters('LS_AKV')]", + "type":"LinkedServiceReference" + }, + "secretName":{ + "value":"@pipeline().parameters.ClientSecretKeyVaultSecretName", + "type":"Expression" + } + } + } + } + }, + { + "name":"StatusUntilPowerBIRefreshes", + "description":"This activity would wait until power bi dataset/dataflow has completely refreshed", + "type":"Until", + "dependsOn":[ + { + "activity":"TriggerPowerBIRefresh", + "dependencyConditions":[ + "Succeeded" + ] + } + ], + "userProperties":[ + + ], + "typeProperties":{ + "expression":{ + "value":"@not(equals(first(json(string(activity('GetRefreshDetails').output)).value).status,if(equals(toUpper(pipeline().parameters.EntityType),'DATASET'),'Unknown','InProgress')))", + "type":"Expression" + }, + "activities":[ + { + "name":"ACT_Cmn_WaitFor300Sec", + "description":"This activity would wait for 300 sec", + "type":"Wait", + "dependsOn":[ + + ], + "userProperties":[ + + ], + "typeProperties":{ + "waitTimeInSeconds":300 + } + }, + { + "name":"GetRefreshDetails", + "description":"This activity fetches refresh details of Dataset / Dataflow", + "type":"WebActivity", + "dependsOn":[ + { + "activity":"ACT_Cmn_WaitFor300Sec", + "dependencyConditions":[ + "Succeeded" + ] + } + ], + "policy":{ + "timeout":"7.00:00:00", + "retry":0, + "retryIntervalInSeconds":30, + "secureOutput":false, + "secureInput":false + }, + "userProperties":[ + + ], + "typeProperties":{ + "url":{ + "value":"@concat('https://api.powerbi.com/v1.0/myorg/groups/',pipeline().parameters.WorkspaceId,if(equals(toUpper(pipeline().parameters.EntityType),'DATASET'),'/datasets/','/dataflows/'),pipeline().parameters.EntityId,if(equals(toUpper(pipeline().parameters.EntityType),'DATASET'),'/refreshes?$top=1','/transactions?$top=1'))", + "type":"Expression" + }, + "method":"GET", + "headers":{ + + }, + "authentication":{ + "type":"ServicePrincipal", + "userTenant":{ + "value":"@pipeline().parameters.TenantId", + "type":"Expression" + }, + "username":{ + "value":"@pipeline().parameters.ClientId", + "type":"Expression" + }, + "resource":"https://analysis.windows.net/powerbi/api", + "password":{ + "type":"AzureKeyVaultSecret", + "store":{ + "referenceName":"[parameters('LS_AKV')]", + "type":"LinkedServiceReference" + }, + "secretName":{ + "value":"@pipeline().parameters.ClientSecretKeyVaultSecretName", + "type":"Expression" + } + } + } + } + } + ], + "timeout":"0.04:00:00" + } + }, + { + "name":"IfRefreshFailed", + "description":"This activity would check if refresh has failed and would throw error", + "type":"IfCondition", + "dependsOn":[ + { + "activity":"StatusUntilPowerBIRefreshes", + "dependencyConditions":[ + "Succeeded" + ] + } + ], + "userProperties":[ + + ], + "typeProperties":{ + "expression":{ + "value":"@equals(first(json(string(activity('GetRefreshDetails').output)).value).status,'Failed')", + "type":"Expression" + }, + "ifTrueActivities":[ + { + "name":"ThrowErrorOnFailure", + "description":"This fail activity would provide error message for refresh failure", + "type":"Fail", + "dependsOn":[ + + ], + "userProperties":[ + + ], + "typeProperties":{ + "message":{ + "value":"@if(equals(toUpper(pipeline().parameters.EntityType),'DATAFLOW'),concat(pipeline().parameters.EntityName,' failed to refresh'),string(json(first(json(string(activity('GetRefreshDetails').output))?.value)?.serviceExceptionJson)))", + "type":"Expression" + }, + "errorCode":"51000" + } + } + ] + } + } + ], + "policy":{ + "elapsedTimeMetric":{ + + }, + "cancelAfter":{ + + } + }, + "parameters":{ + "WorkspaceId":{ + "type":"string" + }, + "EntityId":{ + "type":"string" + }, + "EntityType":{ + "type":"string" + }, + "EntityName":{ + "type":"string" + }, + "TenantId":{ + "type":"string" + }, + "ClientId":{ + "type":"string" + }, + "ClientSecretKeyVaultSecretName":{ + "type":"string" + } + }, + "annotations":[ + + ], + "lastPublishTime":"2022-11-07T18:03:52Z" + }, + "dependsOn":[ + + ] + } + ] +}