Azure Functions から Power BI の XMLA エンドポイントに接続してデータを取得する

Power BI Premium で、[XMLA エンドポイントが利用できるようになりました](https://docs.microsoft.com/ja-jp/power-bi/admin/service-premium-connect-tools)。XMLA エンドポイントは Microsoft Analysis Services にアクセスする際に利用するプロトコルです。これにより、Azure Analysis Services と SQL Server Analysis Services の接続に使う[ライブラリ](https://docs.microsoft.com/ja-jp/analysis-services/client-libraries?view=azure-analysis-services-current) を利用して、Power BI Service に接続する事ができます。
本記事では、Power BI Service の XMLAエンドポイントに Azure Functions にデプロイしたC# のプログラムから接続し、データを取得する方法を紹介します。
# 全体の手順
手順の概要は以下となります。
1. Azure AD でサービスプリンシパルを作成
2. セキュリティグループを作成し、サービスプリンシパルを追加
3. Power BI テナントでサービスプリンシパルのアクセス許可
4. Power BI Premium で、XMLA エンドポイントのアクセスを許可
5. ワークスペースを作成し、サービスプリンシパルをワークスペースの管理者に設定
6. ワークスペースにテスト用のデータセットをデプロイ
7. DAX Studio を利用して DAX 関数を作成
8. Azure Functions にプログラムをデプロイ
9. Azure Functions に環境変数の設定
10. Azure Functions にアクセスしてテスト

# 各手順の詳細
以下は上記の1～10の手順の詳細です。
## Azure AD でサービスプリンシパルを作成
Azure Portal にログインして、Azure Active Directory から「アプリの登録」-「+新規作成」をクリックします。

|![アプリの登録](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/0c9c24ac-a57f-5dd0-ef18-1abfff446f98.png)|
|:--|


表示名を入力し、登録をクリックします。

|![アプリの登録](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/c7833bdc-2305-c1f6-2b16-87c492a265ab.png)|
|:--|
「アプリケーション(クライアント)ID」と「ディレクトリ(テナント)ID」をコピーして保存しておきます。サービスプリンシパルのユーザ名として"app:<アプリケーション(クライアント)ID>@<ディレクトリ(テナント)ID>"形式で後で使用します。具体的には"app:5eb07315-a268-4e29-aec8-02ec0ff1c345@xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" のような形式となります。  

|![IDの確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/34134146-66ba-be06-fd44-6ba4c6ba5c46.png)|
|:--|


左側で「証明書とシークレット」を選択して、新しいクライアントシークレットを作成します。

|![シークレットの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/84f0f448-858f-6ff0-bb31-7209ea7c8d64.png)|
|:--|
「説明」を入力し追加をクリックします。

|![シークレットの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/d55e5773-6c6b-3da1-8865-2dab6553846e.png)|
|:--|
作成されたクライアントシークレットの値をクリップボートにコピーして保存しておきます。この画面から移動すると二度と確認する事ができまんので、ここで忘れずコピーして下さい。後程サービスプリンシパルでログインする際のパスワードとして利用します。

|![シークレットの保存](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/72502e44-d146-9723-a211-469a651b2b67.png)|
|:--|
## セキュリティグループを作成し、サービスプリンシパルを追加
全てのサービスプリンシパルから Power BI にアクセス許可するのではなく、特定のセキュリティグループに属しているサービスプリンシパルのみを許可する為に、セキュリティグループを作成します。
Azure Portal で 「Azure Active Directory」 - 「グループ」-「+新しいグループ」をクリックします。

|![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/634f11c0-72b0-af5c-44b9-318d8e809576.png)|
|:--|
グループの種類、グループ名、グループの説明を入力し「作成」をクリックします。

|![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/f7a2b937-a37d-e6c2-c5d1-ba431ab634b2.png)|
|:--|

作成したグループに、あらかじめ作成しておいたサービスプリンシパルをメンバーとして追加します。

|![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/05006886-f2cf-a854-3239-8a383d741e80.png)|
|:--|

## Power BI テナントでサービスプリンシパルのアクセス許可
Power BI 管理ポータルで、 [テナント設定] を選択します。
[Power BI API の使用をサービスプリンシパルに許可]を展開し、「有効化」と「特定のセキュリティ グループ (推奨)」を選択し、アクセス許可するセキュリティグループを指定します。

|![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/4b44ba19-7427-f298-e647-d809ca28bf9e.png)|
|:--|

## Power BI Premium で、XMLA エンドポイントのアクセスを許可
Power BI 管理ポータルで、 [容量の設定] > [Power BI Premium] > 容量の名前を選択します。
[ワークロード] を展開します。 [XMLA エンドポイント] の設定で、 [読み取り専用]または「読み取り、書き込み」を選択します。

|![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/3fc2c385-7b50-78c7-907f-ca588b467e47.png)|
|:--|

## ワークスペースを作成し、サービスプリンシパルをワークスペースの管理者に設定
Power BI Service の画面から「ワークスペースの作成」をクリックします。

|![13.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/8a1f59ee-8e4b-1722-bdc3-01480073aa97.png)|
|:--|

ワークスペース名を入力します。

|![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/57d68902-59ec-8016-d0ec-0bc5612a0da7.png)|
|:--|

詳細を展開し、Premium容量がオンになっている事を確認して作成します。

|![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/56a33682-f843-a22a-5ceb-3251ce29c3d8.png)|
|:--|

作成したワークスペースの「アクセス」をクリックして、サーパスプリンパルのユーザ名を追加します。

|![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/86180989-9055-2e1b-5b2f-377361fff209.png)|
|:--|

作成したワークスペースの「設定」をクリックして、ワークスペース接続の文字列をコピーしておきます。XMLAエンドポイントへ接続する際の文字列となります。

|![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/e6561519-3ad0-33a1-a064-ccbe6b56fa83.png)|
|:--|

## ワークスペースにテスト用のデータセットをデプロイ
テスト用のデータセットとして、[Power BI のサンプルが公開されている github ](https://github.com/microsoft/powerbi-desktop-samples/tree/main/Sample%20Reports) から [Sales & Returns Sample v201912.pbix](https://github.com/microsoft/powerbi-desktop-samples/blob/main/Sample%20Reports/Sales%20%26%20Returns%20Sample%20v201912.pbix) をダウンロードして利用します。

ダウンロードした、Sales & Returns Sample v201912.pbix を Power BI Desktop で開き、Power BI Premium の容量のワークスペースに発行します。


|![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/ce4dcb26-e499-9a10-8469-95efe2978b94.png)|
|:--|

発行するワークスペースを選択します。

|![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/5bf08dfa-f94e-0f1c-4401-f3c8b07ddbba.png)|
|:--|

## DAX Studio を利用して DAX 関数を作成
[https://daxstudio.org/](https://daxstudio.org/) から、DAX Studio をダウンロードしてインストールして起動します。

Connect の画面で、tablular Server を選択し、ワークスペース接続の文字列を入力します。

|![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/09ca417a-b56f-cd3c-b19a-801a1762ceba.png)|
|:--|

ユーザとパスワードを入力するとすると、左側のペインにデータセットが表示されます。「Query Builder」をクリックすると表示される領域に、データ取得したいカラムとメジャーを左側のデータセットからドラッグアンドドロップします。Edit Query をクリックすると、データ取得の為の DAX Query が表示されます。Run Query をクリックすると結果が表示されます。

|![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/b5c75c10-f3cd-680b-5938-fabbd91b1c69.png)|
|:--|

ここでは、左上のデータ名を右クリックして Database Name をコピーします。また DAX Query もコピーしてきます。

|![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/643b4907-0c69-e176-0b07-8e971421bcd8.png)|
|:--|

|Database Name|DAX Query|
|:--|:--|
|Sales & Returns Sample v201912|EVALUATE <br> SUMMARIZECOLUMNS(<BR>    'Product'[Product],<BR>"Returns", [Returns]<BR>)|

## Azure Functions にプログラムをデプロイ
GitHub上のサンプルプログラムを Azure Functions にデプロイします。
[https://github.com/sushima/XMLASample/](https://github.com/sushima/XMLASample/)

デプロイ先は Azure を選択します。

|![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/f36708ff-fd99-1689-7f8d-751a2f496edb.png)|
|:--|

ターゲットは Azure Function App(Windnows) を選択します。

|![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/f6b220a8-567e-a72a-30c5-f484b04a120b.png)|
|:--|

デプロイする Functions は新規作成します。

|![23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/ce047368-240d-77c5-5c8b-c5655f3bc0d6.png)|
|:--|

## Azure Functions に環境変数の設定
Azure Portal で作成した Functions を開き「構成」をクリックして新しいアプリケーション設定を追加します。

|![24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/a27d6152-a47f-9443-3344-511fe86a28e6.png)|
|:--|

追加するのは以下の3つの設定です。


|名前|値|説明|
|:--|:--|:--|
|PBI_CONNECTION_STRING|Provider=MSOLAP.8;Data Source=powerbi://api.powerbi.com/v1.0/myorg/XMLTEST|XMLTESTの部分は実際のワークスペース名に応じて変更して下さい。|
|appId|app:5eb07315-a268-4e29-aec8-02ec0ff1c345@xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx|実際の<アプリケーション(クライアント)ID>@<ディレクトリ(テナント)ID>を設定して下さい。|
|authKey|l3kaAAA~AAAA_~5A4AA-Sh1~alAAAAAA6|実際のサービスプリンシパルのシークレットの値を設定して下さい。|

設定後は忘れずに「保存」をクリックしてください。

## Azure Functions にアクセスしてテスト
Azure Portal から、デプロイした関数を選択して「関数のURLの取得」をクリックして、URLをコピーします。

|![25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/d05129ec-646b-7c63-bcef-6f9cf2d8dffa.png)|
|:--|

コピーした URL に以下の2つの引数を追加してブラウザからアクセスします。

|引数|値|説明|
|:--|:--|:--|
|catalog|Sales%20%26%20Returns%20Sample%20v201912|Database NameをURLエンコードした文字列|
|query|EVALUATE%0D%0ASUMMARIZECOLUMNS%28%0D%0A%27Product%27%5BProduct%5D%2C%0D%0A%22Returns%22%2C%20%5BReturns%5D%0D%0A%29%0D%0A|Dax QueryをURLエンコードした文字列|

以下のように JSON 形式で結果が返ってくれば成功です。

|![26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609009/fe56b1bd-9397-1109-b74b-5b9c569e7886.png)|
|:--|

# おわりに
プログラムから Power BI の XMLA エンドポイントにアクセスする事で、プログラムからデータを取得することが可能になりますので、ご参考にして頂ければ幸いです。