(メモ)Visual Studio 2015 の Azure Functions プロジェクトに 参照サービスを追加する

Functions単体では、ただコードを書いて、日付を返すとかはできますが、それだけでは、日付を返すとか文字列を変換するとかのことはできても、それは普通にローカルで動くプログラムでも得られるわけで、あまり意味がありません。
Functionsのプロジェクトを他のサービスに接続してみます。

 

プロジェクトのコンテキストメニュー(失敗)

ソリューションエクスプローラー>Functionsプロジェクト>コンテキストメニュー>追加>Connected Service

2016-12-03-1

追加用の画面が表示される
2016-12-03

Azure Storageを選ぶ
2016-12-03-2

既存を選ぶか、Create a New Storage Accountで新規に追加

2016-12-03-3

  1. Azure サブスクリプション を関連付けられているアカウントを選択
  2. サブスクリプションを選択
  3. Storage Account のURLになるものを入力
  4. お好みで料金体系・サービス体系を選択
  5. リソースグループを選択(ここで新規で作ることもできる)
  6. Locationを選択

Azure Storageの画面でAddとしてみると・・・

2016-12-03-4

NuGetのパッケージを追加できずにエラー。
というわけで、この方法ではだめな様子。
ひとまずフィードバックを送信。

functions の場合、プロジェクトの参照というよりは、bindingの定義があってという感じなのもあるかもしれないのでひとまずこの方法ではなさそう。

Functionsの追加から

試しにFunctionの追加から、
テンプレートは、FaceLocatorという、Blobストレージにある画像から顔がある四角形領域を返してくれるもの。

2016-12-03-5

ストレージアカウントの接続文字列を入力する欄が赤くなってますので、ポータルから引っ張ってくる。

2016-12-03-6

この接続文字列は絶対に公開しないように・・・
このように公開してしまった場合は、アカウントを消すか、接続文字列を再生成する必要が出てくる。その場合既存の接続文字列は使えなくなるので、いろいろ面倒。

追加した「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であり今後変わる可能性があると思うが、
現状動くポータルを正解としていけば動かす道は掴んでいけそうであることがわかった。