AzureFunctionsでローカルでAzure Blob Storage Triggerな環境構築を行う

# はじめに
前回の記事でHTTP TriggerなAzure Functionsを作成しました。
前回作成したものにAzure Blob Storage Triggerの機能を今回は追加したいと思います。

https://qiita.com/itita/items/d102fc969e3d87e73d28

# 環境
* Windows11
* Visual Studio Code
* Azure Functions Core Tools v4.0
* Microsoft Azure Storage Explorer

# ①Azure Blob Storage Triggerを追加する
Azureマークをクリックしその後、WorkSpaceのFunctionマークをクリックします。
![Func1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/ab059cd4-e81c-4eee-f008-25947913df91.png)

その後、以下を順にクリックしていきます。
1. Azure Blob Storage trigger
1. BlobTrigger1(機能名、今回はデフォルトのままです)
1. Company.Function(namespace、今回はデフォルトのままです)
1. AzureWebJobsStorage(local.settings.jsonになければ追加します。)
1. samples-workitems(監視するストレージ名)

※4に関して補足
```json
{
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    }
}
```

作成後はBlobTrigger1.csが追加されていると思います。
![スクリーンショット 2022-12-04 213641.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/01467c8b-d0a3-6278-9192-b0772edad29c.png)

# ②Azure Blob Storage Triggerの稼働確認
1. Ctrl + Shift + Pでコマンドパレットを開き「Azurite: Start」をクリックします。
2. デバッグ実行します。(F5キー)
3. Azure Storage Explorerを開き、エミュレータのBlobコンテナに「samples-workitems」コンテナを作成します。
4. 作成後、適当なファイルをアップロードしてみます。
※今回はtest.txtというファイルをアップロードしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/a0d3d4e1-1ee8-ee7e-1245-d286bb4dc929.png)
アップロード後、VSCodeのターミナルを確認すると以下のようなものが出力されていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/3b4a5080-c4b1-6ad2-973a-218567f9da4c.png)

# 番外編：HTTP Triggerで受け取った文字列をBlobにアップロードし、さらにそれをAzure Blob Storage Triggerする
## ①Requestの文字列を取得しその文字列をBlobにアップロードする
※前回作成分に追記
<details><summary>Utility/AzureStorageClientUtility.cs</summary>

```csharp
using System;
using System.Threading.Tasks;
using Azure;
using Azure.Storage.Blobs;

namespace Company.Function.Utility
{
    public class AzureStorageClientUtility
    {
        /// <summary>
        /// コンテナクライアント
        /// 接続文字列はAzuriteでのエミュレータ共有キー資格情報
        /// </summary>
        BlobServiceClient blobServiceClient = new BlobServiceClient("DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;");

        /// <summary>
        /// Blobに文字列をアップロードする
        /// 今回追加
        /// </summary>
        public async Task<BlobContainerClient> UploadFileAsync(string name)
        {
            BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("samples-workitems");
            BlobClient blobClient = containerClient.GetBlobClient(name);
            await blobClient.UploadAsync(BinaryData.FromString(name), overwrite: true);
            return null;
        }
    }
}
```
</details>
<details><summary>HttpTrigger1.cs</summary>

```csharp
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Company.Function.Utility;

namespace Company.Function
{
    public static class HttpTrigger1
    {
        [FunctionName("HttpTrigger1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            // 今回追加
            AzureStorageClientUtility azureUtility = new AzureStorageClientUtility();
            if (!string.IsNullOrWhiteSpace(name))
            {
                await azureUtility.UploadFileAsync(name);
            }

            return new OkObjectResult(responseMessage);
        }
    }
}
```
</details>

## ②稼働確認
デバッグ実行し、APIRequestしてみる
```powershell
Invoke-WebRequest -Uri "http://localhost:7071/api/HttpTrigger1" `
                  -Method POST `
                  -Headers @{"Content-Type"="application/json"} `
                  -Body "{'name':'hello world'}"
```
Azure Storage Explorerにファイルが作成されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/cc39f674-e4f2-b7b5-9bdc-a0def64b2f59.png)

アップロード後、VSCodeのターミナルを確認すると以下のようなものが出力されていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/b52c9569-75dd-9bef-93ed-d9834b3075c9.png)

<details><summary>おまけ</summary>

```powershell
# powershellバージョン要確認
1..10 | ForEach-Object -Parallel { Invoke-WebRequest -Uri "http://localhost:7071/api/HttpTrigger1" -Method POST  -Headers @{"Content-Type"="application/json"}  -Body "{'name':$_}" }
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/afb3476e-fc77-52d1-8c59-efd5775a9483.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819390/59bc980d-86c3-987a-dccc-34984a4720b3.png)

</details>

# 所感
今回は前回の機能に追加でローカルでAzure Blob Storage Triggerな環境構築を行いました。
まだまだAzure Functionsには機能があるので深堀していけたらよいなと思います。
今後もいろいろチャレンジしてみたいと思います。