diff --git a/data_migration_tools/server/package-lock.json b/data_migration_tools/server/package-lock.json index 5987ef1..c1c2143 100644 --- a/data_migration_tools/server/package-lock.json +++ b/data_migration_tools/server/package-lock.json @@ -3107,9 +3107,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "devOptional": true, "bin": { "acorn": "bin/acorn" @@ -12333,9 +12333,9 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "devOptional": true }, "acorn-import-assertions": { diff --git a/data_migration_tools/server/src/features/delete/delete.controller.ts b/data_migration_tools/server/src/features/delete/delete.controller.ts index 94567ca..ed81c5a 100644 --- a/data_migration_tools/server/src/features/delete/delete.controller.ts +++ b/data_migration_tools/server/src/features/delete/delete.controller.ts @@ -11,6 +11,7 @@ import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { Request } from "express"; import { DeleteService } from "./delete.service"; import { DeleteResponse } from "./types/types"; +import { makeContext } from "src/common/log"; @ApiTags("delete") @Controller("delete") @@ -33,7 +34,9 @@ export class DeleteController { }) @Post() async deleteData(): Promise<{}> { - await this.deleteService.deleteData(); + const context = makeContext("tool", "delete"); + + await this.deleteService.deleteData(context); return {}; } } diff --git a/data_migration_tools/server/src/features/delete/delete.service.ts b/data_migration_tools/server/src/features/delete/delete.service.ts index 9ade573..3055d5b 100644 --- a/data_migration_tools/server/src/features/delete/delete.service.ts +++ b/data_migration_tools/server/src/features/delete/delete.service.ts @@ -3,6 +3,7 @@ import { DeleteRepositoryService } from "../../repositories/delete/delete.reposi import { makeErrorResponse } from "../../common/errors/makeErrorResponse"; import { AdB2cService } from "../../gateways/adb2c/adb2c.service"; import { BlobstorageService } from "../../gateways/blobstorage/blobstorage.service"; +import { Context } from "../../common/log"; @Injectable() export class DeleteService { @@ -17,21 +18,34 @@ export class DeleteService { * データを削除する * @returns data */ - async deleteData(): Promise { - this.logger.log(`[IN] ${this.deleteData.name}`); + async deleteData(context: Context): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.deleteData.name}` + ); try { // BlobStorageからデータを削除する - await this.blobstorageService.deleteContainers(); + await this.blobstorageService.deleteContainers(context); - // ADB2Cからユーザ情報を取得する - const users = await this.adB2cService.getUsers(); - const externalIds = users.map((user) => user.id); - await this.adB2cService.deleteUsers(externalIds); + // 100件ずつのユーザー取得なのですべて削除するまでループする + for (let i = 0; i < 500; i++) { + // ADB2Cからユーザ情報を取得する + const { users, hasNext } = await this.adB2cService.getUsers(context); + + // ユーザーがいない場合はループを抜ける + if (!hasNext) { + break; + } + + const externalIds = users.map((user) => user.id); + await this.adB2cService.deleteUsers(context, externalIds); + } // データベースからデータを削除する await this.deleteRepositoryService.deleteData(); // AutoIncrementの値をリセットする await this.deleteRepositoryService.resetAutoIncrement(); + // 初期データを挿入する + await this.deleteRepositoryService.insertInitData(context); } catch (e) { this.logger.error(`error=${e}`); if (e instanceof Error) { diff --git a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts index b561f42..5ba0f0e 100644 --- a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts +++ b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts @@ -30,14 +30,10 @@ export const isConflictError = (arg: unknown): arg is ConflictError => { export class AdB2cService { private readonly logger = new Logger(AdB2cService.name); private readonly tenantName: string; - private readonly flowName: string; - private readonly ttl: number; private graphClient: Client; constructor(private readonly configService: ConfigService) { this.tenantName = this.configService.getOrThrow("TENANT_NAME"); - this.flowName = this.configService.getOrThrow("SIGNIN_FLOW_NAME"); - this.ttl = this.configService.getOrThrow("ADB2C_CACHE_TTL"); // ADB2Cへの認証情報 const credential = new ClientSecretCredential( @@ -111,8 +107,10 @@ export class AdB2cService { * @param externalIds * @returns users */ - async getUsers(): Promise { - this.logger.log(`[IN] ${this.getUsers.name}`); + async getUsers( + context: Context + ): Promise<{ users: AdB2cUser[]; hasNext: boolean }> { + this.logger.log(`[IN] [${context.getTrackingId()}] ${this.getUsers.name}`); try { const res: AdB2cResponse = await this.graphClient @@ -121,7 +119,7 @@ export class AdB2cService { .filter(`creationType eq 'LocalAccount'`) .get(); - return res.value; + return { users: res.value, hasNext: !!res["@odata.nextLink"] }; } catch (e) { this.logger.error(`error=${e}`); const { statusCode } = e; @@ -177,9 +175,11 @@ export class AdB2cService { * Azure AD B2Cからユーザ情報を削除する(複数) * @param externalIds 外部ユーザーID */ - async deleteUsers(externalIds: string[]): Promise { + async deleteUsers(context: Context, externalIds: string[]): Promise { this.logger.log( - `[IN]${this.deleteUsers.name} | params: { externalIds: ${externalIds} };` + `[IN] [${context.getTrackingId()}] ${ + this.deleteUsers.name + } | params: { externalIds: ${externalIds} };` ); try { diff --git a/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts b/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts index 7c26388..ee603c6 100644 --- a/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts +++ b/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts @@ -89,8 +89,10 @@ export class BlobstorageService { * すべてのコンテナを削除します。 * @returns containers */ - async deleteContainers(): Promise { - this.logger.log(`[IN] ${this.deleteContainers.name}`); + async deleteContainers(context: Context): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.deleteContainers.name}` + ); try { for await (const container of this.blobServiceClientAU.listContainers({ diff --git a/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts b/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts index 52539c0..f436207 100644 --- a/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts +++ b/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts @@ -1,11 +1,15 @@ import { Injectable } from "@nestjs/common"; import { DataSource } from "typeorm"; import { logger } from "@azure/identity"; -import { Account } from "./entity/account.entity"; import { AUTO_INCREMENT_START } from "../../constants"; +import { Term } from "./entity/term.entity"; +import { insertEntities } from "../../common/repository"; +import { Context } from "../../common/log"; @Injectable() export class DeleteRepositoryService { + // クエリログにコメントを出力するかどうか + private readonly isCommentOut = process.env.STAGE !== "local"; constructor(private dataSource: DataSource) {} /** @@ -54,4 +58,35 @@ export class DeleteRepositoryService { await queryRunner.release(); } } + + /** + * 初期データを挿入する + * @returns data + */ + async insertInitData(context: Context): Promise { + await this.dataSource.transaction(async (entityManager) => { + const termRepo = entityManager.getRepository(Term); + + // ワークフローのデータ作成 + const newTarmDpa = new Term(); + newTarmDpa.document_type = "DPA"; + newTarmDpa.version = "V0.1"; + const newTarmEula = new Term(); + newTarmEula.document_type = "EULA"; + newTarmEula.version = "V0.1"; + const newTarmPrivacyNotice = new Term(); + newTarmPrivacyNotice.document_type = "PrivacyNotice"; + newTarmPrivacyNotice.version = "V0.1"; + + const initTerms = [newTarmDpa, newTarmEula, newTarmPrivacyNotice]; + + await insertEntities( + Term, + termRepo, + initTerms, + this.isCommentOut, + context + ); + }); + } }