Functions単体では、ただコードを書いて、日付を返すとかはできますが、それだけでは、日付を返すとか文字列を変換するとかのことはできても、それは普通にローカルで動くプログラムでも得られるわけで、あまり意味がありません。
Functionsのプロジェクトを他のサービスに接続してみます。
プロジェクトのコンテキストメニュー(失敗)
ソリューションエクスプローラー>Functionsプロジェクト>コンテキストメニュー>追加>Connected Service
既存を選ぶか、Create a New Storage Accountで新規に追加
- Azure サブスクリプション を関連付けられているアカウントを選択
- サブスクリプションを選択
- Storage Account のURLになるものを入力
- お好みで料金体系・サービス体系を選択
- リソースグループを選択(ここで新規で作ることもできる)
- Locationを選択
Azure Storageの画面でAddとしてみると・・・
NuGetのパッケージを追加できずにエラー。
というわけで、この方法ではだめな様子。
ひとまずフィードバックを送信。
functions の場合、プロジェクトの参照というよりは、bindingの定義があってという感じなのもあるかもしれないのでひとまずこの方法ではなさそう。
Functionsの追加から
試しにFunctionの追加から、
テンプレートは、FaceLocatorという、Blobストレージにある画像から顔がある四角形領域を返してくれるもの。
ストレージアカウントの接続文字列を入力する欄が赤くなってますので、ポータルから引っ張ってくる。
この接続文字列は絶対に公開しないように・・・
このように公開してしまった場合は、アカウントを消すか、接続文字列を再生成する必要が出てくる。その場合既存の接続文字列は使えなくなるので、いろいろ面倒。
追加した「FaceLocatorCSharp」の
function.json
{ "bindings": [ { "type": "blobTrigger", "name": "image", "path": "images/{name}.jpg", "connection": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxxxx;", "direction": "in" }, { "type": "table", "name": "outTable", "tableName": "faceRectangle", "connection": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxxxx;", "direction": "out" } ], "disabled": false }
このファイルにあるbindingsが、作ったfunctionsの入出力の定義そのものになっている。nameにある文字列がfunctionsのメソッドにある引数として以下のように
public static async Task Run(Stream image, string name, IAsyncCollector<FaceRectangle> outTable, TraceWriter log) { .... }
しかし・・・
F5デバッグ開始をしてみるもののエラーが発生してしまう。
かなり手詰まりではあるが、実際に動いているものがあるということはそこから得られるヒントがある・・・と信じて
ポータルから・・・
ポータルから生成したもののソースコードを見てみると
{ "bindings": [ { "type": "blobTrigger", "name": "image", "path": "images/{name}.jpg", "connection": "functionappXXXX", "direction": "in" }, { "type": "table", "name": "outTable", "tableName": "faceRectangle", "connection": "functionappXXXX", "direction": "out" } ], "disabled": false }
といった形で、appSettings.jsonに設定されたものを指定しているようだ。
なので置き換えた。
それでもエラーはまだ残るため次に、テンプレート作成時には空となっていた
AzureWebJobsStorageおよびAzureWebJobsDashboardにも接続文字列を追加した
これは、ポータルで生成した場合は自動的に追加されているものだった。
FaceLocatorのキー
さらにわかったことがあって、テンプレート「FaceLocatorCSharp」では、VisionAPIを使うことになっているが、このための接続情報をappSettingsに追加してやる必要があった。
それがわかるコードはここで
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key"));
「Vision_API_Subscription_Key」という設定値を必要としていたので、appSettings.jsonに追加した。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxx",
"AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxx",
"Vision_API_Subscription_Key": "xxxxxxxxxxxxxxxxx",
"functionapp": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxx"
}
}
もちろんこれは使えるものではなく、
https://www.microsoft.com/cognitive-services/en-us/subscriptions
より取得する必要がある
Visual Studio の拡張機能として
まだ、このFunctionsの拡張機能はPreviewであり今後変わる可能性があると思うが、
現状動くポータルを正解としていけば動かす道は掴んでいけそうであることがわかった。