IoTでAzure Functionを使おう!

2016/4のBuildで、Azure Functionが紹介され、現在、Preview公開されています。
このサービス、とってもGoodです。PaaSでIoTをビルディングブロック的に構築していくときにとっても便利です。従来ならWebJobを使って、各サービス間をつなぐところをFunction使ってより少ない作業量で構築できて、バインディングも増えているし、尚且つ、実行したときだけ課金。さらにはスケール可能。それになんと、Visual Studio Onlineを使って、Visual StudioがPCにインストールされてなくても開発できる!(ステップ実行とかできれば最強なのにぃ。。。)
現在公開中の、IoT Kit ハンズオンV3は、Step 9でWebJob使ってます。Step 8でのStream AnalyticsのMLの結果の出力をEvent Hubに投げていて、投げっぱなし。この二つを近いうちにFunctionを使う様に置き換えようかなと、思っている次第。イメージとしては、こんな感じ

TriggerSignalRByFunction

しかしですね。。。このFunction、一応ドキュメントが、https://azure.microsoft.com/ja-jp/documentation/articles/functions-reference-csharp/ とかから公開されているんですが、BlobやEvent Hubとか、のTriggerを受けるためのバインディングの説明がとても分かりにくいーい、と思ったのは私だけではないはず。結構現時点(2016/6/16)だと、実装されてなくて、ひと手間必要なものも結構あるし。

ということで、function.jsonでのバインディングの定義と、run.csxで定義する、Runメソッドの引数に関する、基本的な事を説明しておきますね。例えば、https://azure.microsoft.com/ja-jp/documentation/articles/functions-bindings-storage/ で、結構使いそうな場面が多い、ストレージへのアクセスをトリガーにしたバインディングが書かれてますね。一個抜き出して解説します。

FunctionBinding

対応を書き込んでます。Function.jsonの、最初の'name'がmyQueueItemというエントリがRunメソッドの一番目の引数に対応、二番目の'name'が'myQueue'というエントリが、Runメソッドの二番目の引数に対応します。Function.jsonのバインディングの定義は増やすことができます。増やしたら、Runメソッドにも同じ名前の引数を追加します。Runメソッドの引数の型は、Functionで使えてバインディング可能な型は、例えばブロブトリガーなら、”ブロブトリガーにサポートされた型”にリストアップされている型なら何でも選択可能。型をどれにするかは、Function.jsonの定義とは関係なく、Runメソッドのロジックの実装上の都合で選択してかまいません。図の例でいうと、図では、myQueueItemはstring ですが、CloudBlockBlobに変えてもよいという事です。バインディングは勝手にAzureがやってくれます。Runメソッドの最後のTraceWriter logは、ログ出力用にデフォルトで付与される変数です

ただ、現状だと、project.jsonに必要なアセンブリの名前を追加したり、run.csxの冒頭に#r や、using宣言を入れる必要はあるので、適宜追加が必要です。実際にやってみたところ、Storage Tableについては、ICollector<T>などは対応していないようです。現状、Storage Tableに行を追加したい場合などはCloudTable型の引数を使わないと動作しませんでした。ICollectorの場合は、function.jsonでのdirection定義がoutになるのですが、CloudTableの場合は、inにしないといけないなど細かい修正は必要ですが、まぁ、プレビュー段階なので臨機応変に対応してくださいね。

今、Functionを取り入れた新しいIoT コンテンツを準備中なので、こうご期待。皆さんもFunctionを是非お試しくださいませ。

おまけ

Azure Functionから、Visual Studio Online(プレビュー)を起動するには、以下の図に従って、クリック&クリック

OpenVSO

そして、ブロックブロブにファイルがアップロードされた時に、そのファイルを解析してストレージに格納したいなら、

project.json

これで、NuGetで公開されている、Azure Storage SDKを組込めます

function.json

現状は、これでStorageに書き込むためのCloudTableの参照を引数で取得できます。
run.csxは、

と書けばいい。

他に、例えば、処理結果をJsonで、ブロブに書き出したい場合は、
project.json

※クラスをシリアライズするので、Newtonsoft.Jsonをインストール

function.json

※出力されるファイルは、pathで指定されたパターンで名前付けられ、保持される。ブロブにimg20160616.jpgというファイルがアップされた場合は、img20160616.jsonという名前で保存される。

run.csx

と書けばOK。myOutputBlobの型はCloudBlockBlobを使います。
ブロブへのアクセス権等は、FunctionのRuntimeが吸収してくれるのでSASToken作るとか考えなくてよいのですごく便利。

以上、おまけとして、Azure Storage テーブルと、ブロブへの出力方法書きました。出力したファイルをStream Analyticsで更に分析したい場合はブロブで、ML で学習データとして使いたい場合は(Import DataはJson対応してないので)、Tableを使うのがベター