## 概要 [Task3880: Azure Functions実装(音声ファイル削除)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3880) - 自動音声ファイル削除を実装 - 上記のテストを実装 - テストにMySQLを使用する仕組みを導入 ## レビューポイント - テストケースは十分か - テスト内容は妥当か - developにデプロイする前の動作確認・ユニットテストとして十分か ## クエリの変更 - 新規処理のため、既存からの変更はなし ## 動作確認状況 - DBが空の状態でローカル環境で実行し、0件削除のログが出ることを確認 - 削除対象が正しいか等はdevelopでチェック予定 - 行った修正がデグレを発生させていないことを確認できるか - 既存処理の変更はなし
147 lines
4.8 KiB
TypeScript
147 lines
4.8 KiB
TypeScript
import {
|
|
BlobServiceClient,
|
|
ContainerClient,
|
|
StorageSharedKeyCredential,
|
|
} from "@azure/storage-blob";
|
|
import {
|
|
BLOB_STORAGE_REGION_AU,
|
|
BLOB_STORAGE_REGION_EU,
|
|
BLOB_STORAGE_REGION_US,
|
|
} from "../constants";
|
|
import { InvocationContext } from "@azure/functions";
|
|
|
|
export class AudioBlobStorageService {
|
|
private readonly sharedKeyCredentialUS: StorageSharedKeyCredential;
|
|
private readonly sharedKeyCredentialEU: StorageSharedKeyCredential;
|
|
private readonly sharedKeyCredentialAU: StorageSharedKeyCredential;
|
|
|
|
private readonly blobServiceClientUS: BlobServiceClient;
|
|
private readonly blobServiceClientEU: BlobServiceClient;
|
|
private readonly blobServiceClientAU: BlobServiceClient;
|
|
|
|
constructor() {
|
|
if (
|
|
!process.env.STORAGE_ACCOUNT_ENDPOINT_US ||
|
|
!process.env.STORAGE_ACCOUNT_ENDPOINT_AU ||
|
|
!process.env.STORAGE_ACCOUNT_ENDPOINT_EU ||
|
|
!process.env.STORAGE_ACCOUNT_NAME_US ||
|
|
!process.env.STORAGE_ACCOUNT_KEY_US ||
|
|
!process.env.STORAGE_ACCOUNT_NAME_AU ||
|
|
!process.env.STORAGE_ACCOUNT_KEY_AU ||
|
|
!process.env.STORAGE_ACCOUNT_NAME_EU ||
|
|
!process.env.STORAGE_ACCOUNT_KEY_EU
|
|
) {
|
|
throw new Error("Storage account information is missing");
|
|
}
|
|
|
|
// リージョンごとのSharedKeyCredentialを生成
|
|
this.sharedKeyCredentialUS = new StorageSharedKeyCredential(
|
|
process.env.STORAGE_ACCOUNT_NAME_US,
|
|
process.env.STORAGE_ACCOUNT_KEY_US
|
|
);
|
|
this.sharedKeyCredentialAU = new StorageSharedKeyCredential(
|
|
process.env.STORAGE_ACCOUNT_NAME_AU,
|
|
process.env.STORAGE_ACCOUNT_KEY_AU
|
|
);
|
|
this.sharedKeyCredentialEU = new StorageSharedKeyCredential(
|
|
process.env.STORAGE_ACCOUNT_NAME_EU,
|
|
process.env.STORAGE_ACCOUNT_KEY_EU
|
|
);
|
|
|
|
// Audioファイルの保存先のリージョンごとにBlobServiceClientを生成
|
|
this.blobServiceClientUS = new BlobServiceClient(
|
|
process.env.STORAGE_ACCOUNT_ENDPOINT_US,
|
|
this.sharedKeyCredentialUS
|
|
);
|
|
this.blobServiceClientAU = new BlobServiceClient(
|
|
process.env.STORAGE_ACCOUNT_ENDPOINT_AU,
|
|
this.sharedKeyCredentialAU
|
|
);
|
|
this.blobServiceClientEU = new BlobServiceClient(
|
|
process.env.STORAGE_ACCOUNT_ENDPOINT_EU,
|
|
this.sharedKeyCredentialEU
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 指定されたファイルを削除します。
|
|
* @param context
|
|
* @param accountId
|
|
* @param country
|
|
* @param fileName
|
|
* @returns file
|
|
*/
|
|
async deleteFile(
|
|
context: InvocationContext,
|
|
accountId: number,
|
|
country: string,
|
|
fileName: string
|
|
): Promise<void> {
|
|
context.log(
|
|
`[IN] ${this.deleteFile.name} | params: { ` +
|
|
`accountId: ${accountId} ` +
|
|
`country: ${country} ` +
|
|
`fileName: ${fileName} };`
|
|
);
|
|
|
|
try {
|
|
// 国に応じたリージョンでコンテナ名を指定してClientを取得
|
|
const containerClient = this.getContainerClient(
|
|
context,
|
|
accountId,
|
|
country
|
|
);
|
|
// コンテナ内のBlobパス名を指定してClientを取得
|
|
const blobClient = containerClient.getBlobClient(fileName);
|
|
|
|
const { succeeded, errorCode, date } = await blobClient.deleteIfExists();
|
|
context.log(
|
|
`succeeded: ${succeeded}, errorCode: ${errorCode}, date: ${date}`
|
|
);
|
|
|
|
// 失敗時、Blobが存在しない場合以外はエラーとして例外をスローする
|
|
// Blob不在の場合のエラーコードは「BlobNotFound」以下を参照
|
|
// https://learn.microsoft.com/ja-jp/rest/api/storageservices/blob-service-error-codes
|
|
if (!succeeded && errorCode !== "BlobNotFound") {
|
|
throw new Error(
|
|
`delete blob failed. succeeded: ${succeeded}, errorCode: ${errorCode}, date: ${date}`
|
|
);
|
|
}
|
|
} catch (e) {
|
|
context.error(`error=${e}`);
|
|
throw e;
|
|
} finally {
|
|
context.log(`[OUT] ${this.deleteFile.name}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 指定してアカウントIDと国に応じたリージョンのコンテナクライアントを取得します。
|
|
* @param context
|
|
* @param accountId
|
|
* @param country
|
|
* @returns
|
|
*/
|
|
private getContainerClient(
|
|
context: InvocationContext,
|
|
accountId: number,
|
|
country: string
|
|
): ContainerClient {
|
|
context.log(
|
|
`[IN] ${this.getContainerClient.name} | params: { ` +
|
|
`accountId: ${accountId}; country: ${country} };`
|
|
);
|
|
|
|
const containerName = `account-${accountId}`;
|
|
if (BLOB_STORAGE_REGION_US.includes(country)) {
|
|
return this.blobServiceClientUS.getContainerClient(containerName);
|
|
} else if (BLOB_STORAGE_REGION_AU.includes(country)) {
|
|
return this.blobServiceClientAU.getContainerClient(containerName);
|
|
} else if (BLOB_STORAGE_REGION_EU.includes(country)) {
|
|
return this.blobServiceClientEU.getContainerClient(containerName);
|
|
} else {
|
|
throw new Error("invalid country");
|
|
}
|
|
}
|
|
}
|