mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
[SQL Migration] Consume more detailed migration states (#20490)
* WIP * Add new states * Missed a few spots * Update logic * Update DatabaseMigrationProperties * Test: add mocks * Update a few more references * Fix warnings * Remove mocks * Update cutover logic * Address PR feedback
This commit is contained in:
@@ -655,7 +655,7 @@ export interface DatabaseMigrationProperties {
|
|||||||
scope: string;
|
scope: string;
|
||||||
provisioningState: 'Succeeded' | 'Failed' | 'Creating';
|
provisioningState: 'Succeeded' | 'Failed' | 'Creating';
|
||||||
provisioningError: string;
|
provisioningError: string;
|
||||||
migrationStatus: 'InProgress' | 'Failed' | 'Succeeded' | 'Creating' | 'Completing' | 'Canceling';
|
migrationStatus: 'Canceled' | 'Canceling' | 'Completing' | 'Creating' | 'Failed' | 'InProgress' | 'ReadyForCutover' | 'Restoring' | 'Retriable' | 'Succeeded' | 'UploadingFullBackup' | 'UploadingLogBackup';
|
||||||
migrationStatusDetails?: MigrationStatusDetails;
|
migrationStatusDetails?: MigrationStatusDetails;
|
||||||
migrationStatusWarnings?: MigrationStatusWarnings;
|
migrationStatusWarnings?: MigrationStatusWarnings;
|
||||||
startedOn: string;
|
startedOn: string;
|
||||||
|
|||||||
@@ -162,19 +162,23 @@ export function filterMigrations(databaseMigrations: azure.DatabaseMigration[],
|
|||||||
return filteredMigration.filter(
|
return filteredMigration.filter(
|
||||||
value => {
|
value => {
|
||||||
const status = getMigrationStatus(value);
|
const status = getMigrationStatus(value);
|
||||||
return status === constants.MigrationStatus.InProgress
|
return status === constants.MigrationState.InProgress
|
||||||
|| status === constants.MigrationStatus.Retriable
|
|| status === constants.MigrationState.ReadyForCutover
|
||||||
|| status === constants.MigrationStatus.Creating;
|
|| status === constants.MigrationState.UploadingFullBackup
|
||||||
|
|| status === constants.MigrationState.UploadingLogBackup
|
||||||
|
|| status === constants.MigrationState.Restoring
|
||||||
|
|| status === constants.MigrationState.Retriable
|
||||||
|
|| status === constants.MigrationState.Creating;
|
||||||
});
|
});
|
||||||
case AdsMigrationStatus.SUCCEEDED:
|
case AdsMigrationStatus.SUCCEEDED:
|
||||||
return filteredMigration.filter(
|
return filteredMigration.filter(
|
||||||
value => getMigrationStatus(value) === constants.MigrationStatus.Succeeded);
|
value => getMigrationStatus(value) === constants.MigrationState.Succeeded);
|
||||||
case AdsMigrationStatus.FAILED:
|
case AdsMigrationStatus.FAILED:
|
||||||
return filteredMigration.filter(
|
return filteredMigration.filter(
|
||||||
value => getMigrationStatus(value) === constants.MigrationStatus.Failed);
|
value => getMigrationStatus(value) === constants.MigrationState.Failed);
|
||||||
case AdsMigrationStatus.COMPLETING:
|
case AdsMigrationStatus.COMPLETING:
|
||||||
return filteredMigration.filter(
|
return filteredMigration.filter(
|
||||||
value => getMigrationStatus(value) === constants.MigrationStatus.Completing);
|
value => getMigrationStatus(value) === constants.MigrationState.Completing);
|
||||||
}
|
}
|
||||||
return filteredMigration;
|
return filteredMigration;
|
||||||
}
|
}
|
||||||
@@ -323,20 +327,25 @@ export function getPipelineStatusImage(status: string | undefined): IconPath {
|
|||||||
export function getMigrationStatusImage(migration: azure.DatabaseMigration): IconPath {
|
export function getMigrationStatusImage(migration: azure.DatabaseMigration): IconPath {
|
||||||
const status = getMigrationStatus(migration);
|
const status = getMigrationStatus(migration);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case constants.MigrationStatus.InProgress:
|
case constants.MigrationState.InProgress:
|
||||||
|
case constants.MigrationState.UploadingFullBackup:
|
||||||
|
case constants.MigrationState.UploadingLogBackup:
|
||||||
|
case constants.MigrationState.Restoring:
|
||||||
return IconPathHelper.inProgressMigration;
|
return IconPathHelper.inProgressMigration;
|
||||||
case constants.MigrationStatus.Succeeded:
|
case constants.MigrationState.ReadyForCutover:
|
||||||
|
return IconPathHelper.cutover;
|
||||||
|
case constants.MigrationState.Succeeded:
|
||||||
return IconPathHelper.completedMigration;
|
return IconPathHelper.completedMigration;
|
||||||
case constants.MigrationStatus.Creating:
|
case constants.MigrationState.Creating:
|
||||||
return IconPathHelper.notStartedMigration;
|
return IconPathHelper.notStartedMigration;
|
||||||
case constants.MigrationStatus.Completing:
|
case constants.MigrationState.Completing:
|
||||||
return IconPathHelper.completingCutover;
|
return IconPathHelper.completingCutover;
|
||||||
case constants.MigrationStatus.Retriable:
|
case constants.MigrationState.Retriable:
|
||||||
return IconPathHelper.retry;
|
return IconPathHelper.retry;
|
||||||
case constants.MigrationStatus.Canceling:
|
case constants.MigrationState.Canceling:
|
||||||
case constants.MigrationStatus.Canceled:
|
case constants.MigrationState.Canceled:
|
||||||
return IconPathHelper.cancel;
|
return IconPathHelper.cancel;
|
||||||
case constants.MigrationStatus.Failed:
|
case constants.MigrationState.Failed:
|
||||||
default:
|
default:
|
||||||
return IconPathHelper.error;
|
return IconPathHelper.error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,41 +158,49 @@ export function hasMigrationOperationId(migration: DatabaseMigration | undefined
|
|||||||
export function canCancelMigration(migration: DatabaseMigration | undefined): boolean {
|
export function canCancelMigration(migration: DatabaseMigration | undefined): boolean {
|
||||||
const status = getMigrationStatus(migration);
|
const status = getMigrationStatus(migration);
|
||||||
return hasMigrationOperationId(migration)
|
return hasMigrationOperationId(migration)
|
||||||
&& (status === loc.MigrationStatus.InProgress ||
|
&& (status === loc.MigrationState.InProgress
|
||||||
status === loc.MigrationStatus.Retriable ||
|
|| status === loc.MigrationState.Retriable
|
||||||
status === loc.MigrationStatus.Creating);
|
|| status === loc.MigrationState.Creating
|
||||||
|
|| status === loc.MigrationState.ReadyForCutover
|
||||||
|
|| status === loc.MigrationState.UploadingFullBackup
|
||||||
|
|| status === loc.MigrationState.UploadingLogBackup
|
||||||
|
|| status === loc.MigrationState.Restoring);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canDeleteMigration(migration: DatabaseMigration | undefined): boolean {
|
export function canDeleteMigration(migration: DatabaseMigration | undefined): boolean {
|
||||||
const status = getMigrationStatus(migration);
|
const status = getMigrationStatus(migration);
|
||||||
return status === loc.MigrationStatus.Canceled
|
return status === loc.MigrationState.Canceled
|
||||||
|| status === loc.MigrationStatus.Failed
|
|| status === loc.MigrationState.Failed
|
||||||
|| status === loc.MigrationStatus.Retriable
|
|| status === loc.MigrationState.Retriable
|
||||||
|| status === loc.MigrationStatus.Succeeded;
|
|| status === loc.MigrationState.Succeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canRetryMigration(migration: DatabaseMigration | undefined): boolean {
|
export function canRetryMigration(migration: DatabaseMigration | undefined): boolean {
|
||||||
const status = getMigrationStatus(migration);
|
const status = getMigrationStatus(migration);
|
||||||
return status === loc.MigrationStatus.Canceled
|
return status === loc.MigrationState.Canceled
|
||||||
|| status === loc.MigrationStatus.Retriable
|
|| status === loc.MigrationState.Retriable
|
||||||
|| status === loc.MigrationStatus.Failed
|
|| status === loc.MigrationState.Failed
|
||||||
|| status === loc.MigrationStatus.Succeeded;
|
|| status === loc.MigrationState.Succeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canCutoverMigration(migration: DatabaseMigration | undefined): boolean {
|
export function canCutoverMigration(migration: DatabaseMigration | undefined): boolean {
|
||||||
const status = getMigrationStatus(migration);
|
const status = getMigrationStatus(migration);
|
||||||
return hasMigrationOperationId(migration)
|
return hasMigrationOperationId(migration)
|
||||||
&& status === loc.MigrationStatus.InProgress
|
|
||||||
&& isOnlineMigration(migration)
|
&& isOnlineMigration(migration)
|
||||||
|
&& (status === loc.MigrationState.ReadyForCutover || status === loc.MigrationState.InProgress) // TODO: InProgress condition can be eventually deprecated
|
||||||
&& isFullBackupRestored(migration);
|
&& isFullBackupRestored(migration);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isActiveMigration(migration: DatabaseMigration | undefined): boolean {
|
export function isActiveMigration(migration: DatabaseMigration | undefined): boolean {
|
||||||
const status = getMigrationStatus(migration);
|
const status = getMigrationStatus(migration);
|
||||||
return status === loc.MigrationStatus.Completing
|
return status === loc.MigrationState.Completing
|
||||||
|| status === loc.MigrationStatus.Retriable
|
|| status === loc.MigrationState.Retriable
|
||||||
|| status === loc.MigrationStatus.Creating
|
|| status === loc.MigrationState.Creating
|
||||||
|| status === loc.MigrationStatus.InProgress;
|
|| status === loc.MigrationState.InProgress
|
||||||
|
|| status === loc.MigrationState.ReadyForCutover
|
||||||
|
|| status === loc.MigrationState.UploadingFullBackup
|
||||||
|
|| status === loc.MigrationState.UploadingLogBackup
|
||||||
|
|| status === loc.MigrationState.Restoring;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isFullBackupRestored(migration: DatabaseMigration | undefined): boolean {
|
export function isFullBackupRestored(migration: DatabaseMigration | undefined): boolean {
|
||||||
|
|||||||
@@ -10,15 +10,20 @@ import { MigrationSourceAuthenticationType } from '../models/stateMachine';
|
|||||||
import { formatNumber, ParallelCopyTypeCodes, PipelineStatusCodes } from './helper';
|
import { formatNumber, ParallelCopyTypeCodes, PipelineStatusCodes } from './helper';
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
export enum MigrationStatus {
|
// mirrors MigrationState as defined in RP
|
||||||
Failed = 'Failed',
|
export enum MigrationState {
|
||||||
Succeeded = 'Succeeded',
|
|
||||||
InProgress = 'InProgress',
|
|
||||||
Canceled = 'Canceled',
|
Canceled = 'Canceled',
|
||||||
|
Canceling = 'Canceling',
|
||||||
Completing = 'Completing',
|
Completing = 'Completing',
|
||||||
Creating = 'Creating',
|
Creating = 'Creating',
|
||||||
Canceling = 'Canceling',
|
Failed = 'Failed',
|
||||||
|
InProgress = 'InProgress',
|
||||||
|
ReadyForCutover = 'ReadyForCutover',
|
||||||
|
Restoring = 'Restoring',
|
||||||
Retriable = 'Retriable',
|
Retriable = 'Retriable',
|
||||||
|
Succeeded = 'Succeeded',
|
||||||
|
UploadingFullBackup = 'UploadingFullBackup',
|
||||||
|
UploadingLogBackup = 'UploadingLogBackup',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ProvisioningState {
|
export enum ProvisioningState {
|
||||||
@@ -824,14 +829,18 @@ export interface LookupTable<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const StatusLookup: LookupTable<string | undefined> = {
|
export const StatusLookup: LookupTable<string | undefined> = {
|
||||||
[MigrationStatus.InProgress]: localize('sql.migration.status.inprogress', 'In progress'),
|
[MigrationState.Canceled]: localize('sql.migration.status.canceled', 'Canceled'),
|
||||||
[MigrationStatus.Succeeded]: localize('sql.migration.status.succeeded', 'Succeeded'),
|
[MigrationState.Canceling]: localize('sql.migration.status.canceling', 'Canceling'),
|
||||||
[MigrationStatus.Creating]: localize('sql.migration.status.creating', 'Creating'),
|
[MigrationState.Completing]: localize('sql.migration.status.completing', 'Completing'),
|
||||||
[MigrationStatus.Completing]: localize('sql.migration.status.completing', 'Completing'),
|
[MigrationState.Creating]: localize('sql.migration.status.creating', 'Creating'),
|
||||||
[MigrationStatus.Retriable]: localize('sql.migration.status.retriable', 'Retriable'),
|
[MigrationState.Failed]: localize('sql.migration.status.failed', 'Failed'),
|
||||||
[MigrationStatus.Canceling]: localize('sql.migration.status.canceling', 'Canceling'),
|
[MigrationState.InProgress]: localize('sql.migration.status.inprogress', 'In progress'),
|
||||||
[MigrationStatus.Canceled]: localize('sql.migration.status.canceled', 'Canceled'),
|
[MigrationState.ReadyForCutover]: localize('sql.migration.status.readyforcutover', 'Ready for cutover'),
|
||||||
[MigrationStatus.Failed]: localize('sql.migration.status.failed', 'Failed'),
|
[MigrationState.Restoring]: localize('sql.migration.status.restoring', 'Restoring'),
|
||||||
|
[MigrationState.Retriable]: localize('sql.migration.status.retriable', 'Retriable'),
|
||||||
|
[MigrationState.Succeeded]: localize('sql.migration.status.succeeded', 'Succeeded'),
|
||||||
|
[MigrationState.UploadingFullBackup]: localize('sql.migration.status.uploadingfullbackup', 'Uploading full backup'),
|
||||||
|
[MigrationState.UploadingLogBackup]: localize('sql.migration.status.uploadinglogbackup', 'Uploading log backup(s)'),
|
||||||
default: undefined
|
default: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -858,9 +867,13 @@ export const ParallelCopyType: LookupTable<string | undefined> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function STATUS_WARNING_COUNT(status: string, count: number): string | undefined {
|
export function STATUS_WARNING_COUNT(status: string, count: number): string | undefined {
|
||||||
if (status === MigrationStatus.InProgress ||
|
if (status === MigrationState.InProgress ||
|
||||||
status === MigrationStatus.Creating ||
|
status === MigrationState.ReadyForCutover ||
|
||||||
status === MigrationStatus.Completing) {
|
status === MigrationState.UploadingFullBackup ||
|
||||||
|
status === MigrationState.UploadingLogBackup ||
|
||||||
|
status === MigrationState.Restoring ||
|
||||||
|
status === MigrationState.Creating ||
|
||||||
|
status === MigrationState.Completing) {
|
||||||
switch (count) {
|
switch (count) {
|
||||||
case 0:
|
case 0:
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ import { IconPathHelper } from '../constants/iconPathHelper';
|
|||||||
import { getCurrentMigrations, getSelectedServiceStatus } from '../models/migrationLocalStorage';
|
import { getCurrentMigrations, getSelectedServiceStatus } from '../models/migrationLocalStorage';
|
||||||
import * as loc from '../constants/strings';
|
import * as loc from '../constants/strings';
|
||||||
import { filterMigrations, getMigrationDuration, getMigrationStatusImage, getMigrationStatusWithErrors, getMigrationTime, MenuCommands } from '../api/utils';
|
import { filterMigrations, getMigrationDuration, getMigrationStatusImage, getMigrationStatusWithErrors, getMigrationTime, MenuCommands } from '../api/utils';
|
||||||
import { getMigrationTargetType, getMigrationMode, getMigrationModeEnum, canCancelMigration, canCutoverMigration } from '../constants/helper';
|
import { getMigrationTargetType, getMigrationMode, canCancelMigration, canCutoverMigration } from '../constants/helper';
|
||||||
import { DatabaseMigration, getResourceName } from '../api/azure';
|
import { DatabaseMigration, getResourceName } from '../api/azure';
|
||||||
import { logError, TelemetryViews } from '../telemtery';
|
import { logError, TelemetryViews } from '../telemtery';
|
||||||
import { SelectMigrationServiceDialog } from '../dialog/selectMigrationService/selectMigrationServiceDialog';
|
import { SelectMigrationServiceDialog } from '../dialog/selectMigrationService/selectMigrationServiceDialog';
|
||||||
import { AdsMigrationStatus, EmptySettingValue, ServiceContextChangeEvent, TabBase } from './tabBase';
|
import { AdsMigrationStatus, EmptySettingValue, ServiceContextChangeEvent, TabBase } from './tabBase';
|
||||||
import { MigrationMode } from '../models/stateMachine';
|
|
||||||
import { DashboardStatusBar } from './DashboardStatusBar';
|
import { DashboardStatusBar } from './DashboardStatusBar';
|
||||||
|
|
||||||
export const MigrationsListTabId = 'MigrationsListTab';
|
export const MigrationsListTabId = 'MigrationsListTab';
|
||||||
@@ -582,8 +581,7 @@ export class MigrationsListTab extends TabBase<MigrationsListTab> {
|
|||||||
private _getMenuCommands(migration: DatabaseMigration): string[] {
|
private _getMenuCommands(migration: DatabaseMigration): string[] {
|
||||||
const menuCommands: string[] = [];
|
const menuCommands: string[] = [];
|
||||||
|
|
||||||
if (getMigrationModeEnum(migration) === MigrationMode.ONLINE &&
|
if (canCutoverMigration(migration)) {
|
||||||
canCutoverMigration(migration)) {
|
|
||||||
menuCommands.push(MenuCommands.Cutover);
|
menuCommands.push(MenuCommands.Cutover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import * as mssql from 'mssql';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { DatabaseMigration, getMigrationDetails } from '../api/azure';
|
import { DatabaseMigration, getMigrationDetails } from '../api/azure';
|
||||||
import { MenuCommands, SqlMigrationExtensionId } from '../api/utils';
|
import { MenuCommands, SqlMigrationExtensionId } from '../api/utils';
|
||||||
import { canCancelMigration, canRetryMigration } from '../constants/helper';
|
import { canCancelMigration, canCutoverMigration, canRetryMigration } from '../constants/helper';
|
||||||
import { IconPathHelper } from '../constants/iconPathHelper';
|
import { IconPathHelper } from '../constants/iconPathHelper';
|
||||||
import { MigrationNotebookInfo, NotebookPathHelper } from '../constants/notebookPathHelper';
|
import { MigrationNotebookInfo, NotebookPathHelper } from '../constants/notebookPathHelper';
|
||||||
import * as loc from '../constants/strings';
|
import * as loc from '../constants/strings';
|
||||||
@@ -158,7 +158,7 @@ export class DashboardWidget {
|
|||||||
try {
|
try {
|
||||||
await this.clearError(args.connectionId);
|
await this.clearError(args.connectionId);
|
||||||
const migration = await this._getMigrationById(args.migrationId, args.migrationOperationId);
|
const migration = await this._getMigrationById(args.migrationId, args.migrationOperationId);
|
||||||
if (canRetryMigration(migration)) {
|
if (canCutoverMigration(migration)) {
|
||||||
const cutoverDialogModel = new MigrationCutoverDialogModel(
|
const cutoverDialogModel = new MigrationCutoverDialogModel(
|
||||||
await MigrationLocalStorage.getMigrationServiceContext(),
|
await MigrationLocalStorage.getMigrationServiceContext(),
|
||||||
migration!);
|
migration!);
|
||||||
|
|||||||
Reference in New Issue
Block a user