diff --git a/data_migration_tools/server/src/features/transfer/transfer.controller.ts b/data_migration_tools/server/src/features/transfer/transfer.controller.ts index 507ed3f..c3c2dce 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.controller.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.controller.ts @@ -194,6 +194,7 @@ export class TransferController { const transferDuplicateAuthorResultUsers = await this.transferService.transferDuplicateAuthor( context, + resultDuplicateEmail.accountsFileLines, resultDuplicateEmail.usersFileLines ); diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts index 60b8d5c..8168c04 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.service.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts @@ -627,11 +627,13 @@ export class TransferService { /** * transferDuplicateAuthor + * @param accountsFileLines: AccountsFile[] * @param usersFileLines: UsersFile[] * @returns UsersFile[] */ async transferDuplicateAuthor( context: Context, + accountsFileLines: AccountsFile[], usersFileLines: UsersFile[] ): Promise { // パラメータ内容が長大なのでログには出さない @@ -642,34 +644,39 @@ export class TransferService { try { const newUsersFileLines: UsersFile[] = []; - let processingAccountId: number = 0; //処理中のアカウントID - let duplicateSequence: number = 2; - let authorIdList: String[] = []; - for (const user of usersFileLines) { - if (user.accountId !== processingAccountId) { - //アカウントIDが別になった場合、通番を初期化する - duplicateSequence = 2; - processingAccountId = user.accountId; - authorIdList = []; - } - let assignAuthorId = user.authorId; - if (authorIdList.includes(user.authorId)) { - // 同じauthorIdがいる場合、自分のauthorIdに連番を付与する - assignAuthorId = assignAuthorId + duplicateSequence; - duplicateSequence = duplicateSequence + 1; - } - authorIdList.push(user.authorId); + for (const accountsFileLine of accountsFileLines) { + let duplicateSequence: number = 2; + let authorIdList: String[] = []; - // 新しいAuthorIdのユーザに詰め替え - const newUser: UsersFile = { - accountId: user.accountId, - userId: user.userId, - name: user.name, - role: user.role, - authorId: assignAuthorId, - email: user.email, - }; - newUsersFileLines.push(newUser); + // メールアドレス重複時はアカウントにもAuthorIdが設定されるので重複チェック用のリストに追加しておく + if (accountsFileLine.authorId) { + authorIdList.push(accountsFileLine.authorId); + } + + const targetaccountUsers = usersFileLines.filter( + (item) => item.accountId === accountsFileLine.accountId + ); + + for (const targetaccountUser of targetaccountUsers) { + let assignAuthorId = targetaccountUser.authorId; + if (authorIdList.includes(targetaccountUser.authorId)) { + // 同じauthorIdがいる場合、自分のauthorIdに連番を付与する + assignAuthorId = assignAuthorId + duplicateSequence; + duplicateSequence = duplicateSequence + 1; + } + authorIdList.push(targetaccountUser.authorId); + + // 新しいAuthorIdのユーザに詰め替え + const newUser: UsersFile = { + accountId: targetaccountUser.accountId, + userId: targetaccountUser.userId, + name: targetaccountUser.name, + role: targetaccountUser.role, + authorId: assignAuthorId, + email: targetaccountUser.email, + }; + newUsersFileLines.push(newUser); + } } return newUsersFileLines; 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 5dbe646..afb2ab2 100644 --- a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts +++ b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts @@ -64,44 +64,57 @@ export class AdB2cService { this.logger.log( `[IN] [${context.getTrackingId()}] ${this.createUser.name}` ); - try { - // ユーザをADB2Cに登録 - const newUser = await this.graphClient.api("users/").post({ - accountEnabled: true, - displayName: username, - passwordPolicies: "DisableStrongPassword", - passwordProfile: { - forceChangePasswordNextSignIn: false, - password: password, - }, - identities: [ - { - signinType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, - issuer: `${this.tenantName}.onmicrosoft.com`, - issuerAssignedId: email, + + const retryCount: number = 3; + let retry = 0; + + while (retry < retryCount) { + try { + // ユーザをADB2Cに登録 + const newUser = await this.graphClient.api("users/").post({ + accountEnabled: true, + displayName: username, + passwordPolicies: "DisableStrongPassword", + passwordProfile: { + forceChangePasswordNextSignIn: false, + password: password, }, - ], - }); - this.logger.log( - `[${context.getTrackingId()}] [ADB2C CREATE] newUser: ${newUser}` - ); - return { sub: newUser.id }; - } catch (e) { - this.logger.error(`[${context.getTrackingId()}] error=${e}`); - if (e?.statusCode === 400 && e?.body) { - const error = JSON.parse(e.body); + identities: [ + { + signinType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: `${this.tenantName}.onmicrosoft.com`, + issuerAssignedId: email, + }, + ], + }); + this.logger.log( + `[${context.getTrackingId()}] [ADB2C CREATE] newUser: ${newUser}` + ); + return { sub: newUser.id }; + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + + if (e?.statusCode === 400 && e?.body) { + const error = JSON.parse(e.body); - // エラーが競合エラーである場合は、メールアドレス重複としてエラーを返す - if (error?.details?.find((x) => x.code === "ObjectConflict")) { - return { reason: "email", message: "ObjectConflict" }; + // エラーが競合エラーである場合は、メールアドレス重複としてエラーを返す + if (error?.details?.find((x) => x.code === "ObjectConflict")) { + return { reason: "email", message: "ObjectConflict" }; + } } - } - throw e; - } finally { - this.logger.log( - `[OUT] [${context.getTrackingId()}] ${this.createUser.name}` - ); + if (++retry < retryCount) { + this.logger.log(`ADB2Cエラー発生。5秒sleepしてリトライします (${retry}/${retryCount})...`); + await new Promise(resolve => setTimeout(resolve, 5000)); + } else { + this.logger.log(`リトライ数が上限に達したのでエラーを返却します`); + throw e; + } + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createUser.name}` + ); + } } }