Azure FunctionsからCosmos DBに出力バインドする(1)~.csx編

Azure Functionsには、その実行に関して「トリガー」「バインド」という概念が存在します。

  • 「トリガー」
    ファンクションの実行のきっかけとなるもの。「1つのファンクション」に「1つのトリガー」が定義されます。
  • 「バインド」
    そのファンクションで処理する入力方向および出力方向のデータを表します。

※Azure Functionsのトリガーとバインドの本質的な解説は以下のあたりを参考に・・・

docs.microsoft.com

1. 今回の実装概要

今回はAzure Functionsの出力バインドとして Cosmos DB を利用する方法についてまとめます。

実装するものは以下のようなイメージになります。

f:id:daigo-knowlbo:20170718235801p:plain

まず、用意する Azure Functions は、HTTPリクエストをトリガーとして実行されます。
FunctionsはCosmos DBを出力バインドとします。

つまり、Azure FunctionsをホストするURLに対してHTTPリクエストが行われると、Functionが実行され、結果としてCosmos DBに対してドキュメントが作成される(出力される)、という動きになります。

前提条件

今回は出力バインドとして Cosmos DB を用います。
ということで、前提条件として以下のような Cosmos DB アカウントを用意していることを前提とします。

f:id:daigo-knowlbo:20170719002117p:plain

API(データモデル)は「SQL (DocumentDB)」です。

2. 2つの実装方式

Azure Functionsは実運用にも耐えうる状態と考えられますが、開発ツールの統合という意味ではまだまだ過渡期的な状況です(2017/7/19現在)。
今回は以下の2つの方法でAzure Functionsを実装します。

  • ① Azureポータルのみを使ったcsxによる実装
    Azureポータル上の操作のみで実装します。実装ファイルはcsx(C#Script)で行います。

  • Visual Studio 2017 Preview(Ver.15.3)を使ったcsコンパイルによる実装
    実装はcsで行います。つまりコンパイルイメージをAzure Functionsにアップします。

共通の初期設定

まず、「1 Azureポータルのみを使ったcsxによる実装」「2 Visual Studio 2017 Preview(Ver.15.3)を使ったcsコンパイルによる実装」の両方に共通の設定を行います。

「Function App」の作成

Azureポータルにログインします。

(1) Function Appの検索

「+新規」をクリックし、検索ボックスに「Function App」と入力します。
候補一覧に表示された「Function App」を選択します。

f:id:daigo-knowlbo:20170719003246p:plain

(2) 作成

「作成」ボタンをクリックします。

f:id:daigo-knowlbo:20170719003305p:plain

(3) パラメータの入力

アプリ名等々を適時入力して「作成」ボタンをクリックします。
ここでは以下の内容としました。
「アプリ名」:RdExampleFunctionApp
「リソースグループ」:RdExampleFunctionApp
ホスティングプラン」:従量課金プラン
「場所」:西日本
「Storage」:新規作成 rdexamplefunctionapp

f:id:daigo-knowlbo:20170719003317p:plain

(4) 作成されたリソースの確認

(3)の後、しばらく待っているとAzure Functionsを構成するリソースが作成されます。
作成したリソースグループ「RdExampleFunctionApp」は以下となります。

f:id:daigo-knowlbo:20170719003434p:plain

「App Serviceプラン」「ストレージ アカウント」「App Service」の3つのリソースが作成されました。
Azure Functionsは基本的にApp Serviceであり、また、その動作の際にはAzure Storageを利用します。その為、上記のような3つのリソースが生成されました。

3. 「① Azureポータルのみを使った.csxによる実装」

では、Functionsの作成に移ります。

3.1 Function Appの選択

リソースグループから(もしくはリソースの一覧から)「RdExampleFunctionApp」を選択します。

f:id:daigo-knowlbo:20170719012632p:plain

3.2 関数の追加

関数の「+」マークをクリックし、右側のペインから「カスタム関数を作成する」をクリックします。

f:id:daigo-knowlbo:20170719012758p:plain

カスタム関数作成画面が表示されます。

f:id:daigo-knowlbo:20170719012922p:plain

以下の作成パラメータを入力します。
テンプレート:「HttpTrigger - C#
関数名の指定:「HttpTrigger1」
承認レベル:「anonymous」 ※認証なしのHTTPリクエストを受け入れるトリガーとします。

「作成」ボタンをクリックすると関数(Azure Function)が作成されます。

3.3 関数の実行

自動生成された HttpTrigger1 ファンクションを実行してみます。

実行ボタンをクリックします。

f:id:daigo-knowlbo:20170719013045p:plain

画面下側の「ログ」ぺインに、コード「log.Info(…)」で実装されたログ文字列が表示されるのを確認することができます。
ひとまず、デフォルトで生成されるファンクションの実行をすることができました。

3.4 Cosmos DB出力バインドの設定

次にCosmos DB出力バインドの設定を行います。
左側のファンクション メニューから「統合」を選択します。

(1) 出力の作成

更に、右側に表示された設定画面から、出力→「+新しい出力」をクリックします。

f:id:daigo-knowlbo:20170719013343p:plain

(2) DocumentDB形式の選択

一覧から「Azure DocumentDB ドキュメント」を選択し「選択」ボタンをクリックします。

f:id:daigo-knowlbo:20170719013714p:plain

(3) 出力バインドの詳細設定

Azure DocumentDB(Cosmos DB)出力バインド設定を行います。
設定項目は以下の通りです。

  • ドキュメントパラメーター名:ファンクションの引数名。この名前で受け取った引数(変数)でCosmos DBのドキュメントを操作します。
  • データベース名:操作対象のデータベース名を設定します。
  • コレクション名:操作対象のコレクション名を設定します。
  • DocumentDBのデータベースとコレクションが作成されるようにしますか?:データベース・コレクションが未作成状態の時に、自動生成するかどうかのフラグを設定します。

f:id:daigo-knowlbo:20170719014130p:plain

続けて「DocumentDBアカウント接続」→「新規」をクリックします。

以下の画面のように、Cosmos DBアカウント一覧が表示されるので、操作対象のCosmos DBアカウント「cosmosdb」を選択します。

f:id:daigo-knowlbo:20170719020722p:plain

以上で、Cosmos DBへの出力バインドの設定が完了しました。
以下が設定完了後の画面です。

f:id:daigo-knowlbo:20170719014743p:plain


※2017/7/20追記
上記、Azureポータル上でのバインド設定は結果として function.json に反映されます(以下の画面)。

f:id:daigo-knowlbo:20170720062042p:plain

AzureポータルGUI操作によるバインド設定は、function.jsonを編集する為のエディタであり、本質的な設定記述場所は function.json となります。


3.5 関数(ファンクション)実装の修正

次に、関数(ファンクション)の実装を修正します。
左側のメニュー(?)から「HttpTrigger1」を選択し、run.csxのエディタ画面を表示します。

f:id:daigo-knowlbo:20170719015146p:plain

実装を以下に修正して、「保存」ボタンをクリックします。

using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, out object outputDocument, TraceWriter log)
{
  string yourName = req.GetQueryNameValuePairs()
    .FirstOrDefault(q => string.Compare(q.Key, "yourName", true) == 0)
    .Value;

  string message = req.GetQueryNameValuePairs()
    .FirstOrDefault(q => string.Compare(q.Key, "message", true) == 0)
    .Value;

  outputDocument = new {
    yourName = yourName,
    message = message
  };


  if (!string.IsNullOrEmpty(yourName) && !string.IsNullOrEmpty(message)) {
    return req.CreateResponse(HttpStatusCode.OK);
  }
  else {
    return req.CreateResponse(HttpStatusCode.BadRequest);
  }
}

実装内容のポイントは、以下の通り。

  • クエリーパラメータとして「yourName」「message」の2つのパラメータを文字列で受けとります。
  • 受け取ったパラメータからCosmos DBのドキュメントを生成します。
  • 引数「outputDocument」は、出力バインド設定「1.4 (3)」の「ドキュメントパラメーター名」と一致している必要があります。

3.6 テスト実行

右側の「テスト」をクリックし、HTTPメソッドを「GET」に設定します。
「クエリ」には「パラメータの追加」で「yourName」および「message」を追加します。
これらは既に実装した関数(ファンクション)の仕様に合わせた呼び出し方法となります。
「実行」ボタンをクリックします。

f:id:daigo-knowlbo:20170719015827p:plain

3.7 テスト結果の確認

AzureポータルでCosmos DB(cosmosdbアカウント)の「データエクスプローラ」を表示します。
以下の画面のように ドキュメント が生成されていることを確認することができます。

f:id:daigo-knowlbo:20170719020058p:plain

4. まとめ(&つづく・・・)

ということで、思ったより長くなったので「(2) Visual Studio 2017 Preview(Ver.15.3)を使ったcsコンパイルによる実装」は、あらためエントリーを分けて投稿したいと思いますm(_ _)m。

おまけ

AzureポータルGUIで設定した Cosmos DB出力バインド による接続文字列設定は、以下の場所に保存されています。
作成した Azure Functions「RdEzampleFunctionApp」を選択し、「アプリケーション設定」を選択します。

f:id:daigo-knowlbo:20170719021239p:plain

「アプリ設定」の下に構成設定として設定値が保存されています。

f:id:daigo-knowlbo:20170719021309p:plain