mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Fix bugbash SQL-Migration extension migration load issues (#16575)
* fix migration refresh issues * merge latest
This commit is contained in:
@@ -13,6 +13,7 @@ import { azureResource } from 'azureResource';
|
||||
import { IconPathHelper } from '../../constants/iconPathHelper';
|
||||
import { CreateResourceGroupDialog } from '../createResourceGroup/createResourceGroupDialog';
|
||||
import * as EventEmitter from 'events';
|
||||
import { clearDialogMessage } from '../../api/utils';
|
||||
|
||||
export class CreateSqlMigrationServiceDialog {
|
||||
|
||||
@@ -89,6 +90,7 @@ export class CreateSqlMigrationServiceDialog {
|
||||
}
|
||||
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
this._selectedResourceGroup = resourceGroup;
|
||||
this._createdMigrationService = await createSqlMigrationService(this._model._azureAccount, subscription, resourceGroup, location, serviceName!, this._model._sessionId);
|
||||
if (this._createdMigrationService.error) {
|
||||
@@ -97,9 +99,6 @@ export class CreateSqlMigrationServiceDialog {
|
||||
this.setFormEnabledState(true);
|
||||
return;
|
||||
}
|
||||
this._dialogObject.message = {
|
||||
text: ''
|
||||
};
|
||||
|
||||
if (this._isBlobContainerUsed) {
|
||||
this._dialogObject.okButton.enabled = true;
|
||||
@@ -511,9 +510,15 @@ export class CreateSqlMigrationServiceDialog {
|
||||
let migrationServiceStatus!: SqlMigrationService;
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
migrationServiceStatus = await getSqlMigrationService(this._model._azureAccount, subscription, resourceGroup, location, this._createdMigrationService.name, this._model._sessionId);
|
||||
break;
|
||||
} catch (e) {
|
||||
this._dialogObject.message = {
|
||||
text: constants.SERVICE_STATUS_REFRESH_ERROR,
|
||||
description: e.message,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
console.log(e);
|
||||
}
|
||||
await new Promise(r => setTimeout(r, 5000));
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { IconPathHelper } from '../../constants/iconPathHelper';
|
||||
import { MigrationContext } from '../../models/migrationLocalStorage';
|
||||
import { MigrationCutoverDialogModel, MigrationStatus } from './migrationCutoverDialogModel';
|
||||
import { MigrationContext, MigrationStatus, ProvisioningState } from '../../models/migrationLocalStorage';
|
||||
import { MigrationCutoverDialogModel } from './migrationCutoverDialogModel';
|
||||
import * as loc from '../../constants/strings';
|
||||
import { convertByteSizeToReadableUnit, convertIsoTimeToLocalTime, getSqlServerName, getMigrationStatusImage, SupportedAutoRefreshIntervals } from '../../api/utils';
|
||||
import { convertByteSizeToReadableUnit, convertIsoTimeToLocalTime, getSqlServerName, getMigrationStatusImage, SupportedAutoRefreshIntervals, clearDialogMessage } from '../../api/utils';
|
||||
import { EOL } from 'os';
|
||||
import { ConfirmCutoverDialog } from './confirmCutoverDialog';
|
||||
import { MigrationMode } from '../../models/stateMachine';
|
||||
@@ -445,7 +445,12 @@ export class MigrationCutoverDialog {
|
||||
}
|
||||
|
||||
private setAutoRefresh(interval: SupportedAutoRefreshIntervals): void {
|
||||
const shouldRefresh = (status: string | undefined) => !status || ['InProgress', 'Creating', 'Completing', 'Creating'].includes(status);
|
||||
const shouldRefresh = (status: string | undefined) => !status
|
||||
|| status === MigrationStatus.InProgress
|
||||
|| status === MigrationStatus.Creating
|
||||
|| status === MigrationStatus.Completing
|
||||
|| status === MigrationStatus.Canceling;
|
||||
|
||||
if (shouldRefresh(this.getMigrationStatus())) {
|
||||
const classVariable = this;
|
||||
clearInterval(this._autoRefreshHandle);
|
||||
@@ -474,6 +479,8 @@ export class MigrationCutoverDialog {
|
||||
}
|
||||
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
|
||||
if (this._isProvisioned() && this._isOnlineMigration()) {
|
||||
this._cutoverButton.updateCssStyles({
|
||||
'display': 'inline'
|
||||
@@ -490,7 +497,10 @@ export class MigrationCutoverDialog {
|
||||
errors.push(this._model.migrationStatus.properties.migrationStatusDetails?.restoreBlockingReason);
|
||||
this._dialogObject.message = {
|
||||
text: errors.filter(e => e !== undefined).join(EOL),
|
||||
level: (this._model.migrationStatus.properties.migrationStatus === MigrationStatus.InProgress || this._model.migrationStatus.properties.migrationStatus === 'Completing') ? azdata.window.MessageLevel.Warning : azdata.window.MessageLevel.Error,
|
||||
level: this._model.migrationStatus.properties.migrationStatus === MigrationStatus.InProgress
|
||||
|| this._model.migrationStatus.properties.migrationStatus === MigrationStatus.Completing
|
||||
? azdata.window.MessageLevel.Warning
|
||||
: azdata.window.MessageLevel.Error,
|
||||
description: this.getMigrationDetails()
|
||||
};
|
||||
const sqlServerInfo = await azdata.connection.getServerInfo((await azdata.connection.getCurrentConnection()).connectionId);
|
||||
@@ -599,12 +609,21 @@ export class MigrationCutoverDialog {
|
||||
if (restoredCount > 0 || isBlobMigration) {
|
||||
this._cutoverButton.enabled = true;
|
||||
}
|
||||
this._cancelButton.enabled = true;
|
||||
} else {
|
||||
this._cutoverButton.enabled = false;
|
||||
this._cancelButton.enabled = false;
|
||||
}
|
||||
|
||||
this._cancelButton.enabled =
|
||||
migrationStatusTextValue === MigrationStatus.Canceling ||
|
||||
migrationStatusTextValue === MigrationStatus.Creating ||
|
||||
migrationStatusTextValue === MigrationStatus.InProgress;
|
||||
|
||||
} catch (e) {
|
||||
this._dialogObject.message = {
|
||||
level: azdata.window.MessageLevel.Error,
|
||||
text: loc.MIGRATION_STATUS_REFRESH_ERROR,
|
||||
description: e.message
|
||||
};
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.isRefreshing = false;
|
||||
@@ -696,7 +715,9 @@ export class MigrationCutoverDialog {
|
||||
|
||||
private _isProvisioned(): boolean {
|
||||
const { migrationStatus, provisioningState } = this._model._migration.migrationContext.properties;
|
||||
return provisioningState === 'Succeeded' || migrationStatus === 'Completing' || migrationStatus === 'Canceling';
|
||||
return provisioningState === ProvisioningState.Succeeded
|
||||
|| migrationStatus === MigrationStatus.Completing
|
||||
|| migrationStatus === MigrationStatus.Canceling;
|
||||
}
|
||||
|
||||
private _isOnlineMigration(): boolean {
|
||||
@@ -713,9 +734,11 @@ export class MigrationCutoverDialog {
|
||||
|
||||
private getMigrationStatus(): string {
|
||||
if (this._model.migrationStatus) {
|
||||
return this._model.migrationStatus.properties.migrationStatus ?? this._model.migrationStatus.properties.provisioningState;
|
||||
return this._model.migrationStatus.properties.migrationStatus
|
||||
?? this._model.migrationStatus.properties.provisioningState;
|
||||
}
|
||||
return this._model._migration.migrationContext.properties.migrationStatus;
|
||||
return this._model._migration.migrationContext.properties.migrationStatus
|
||||
?? this._model._migration.migrationContext.properties.provisioningState;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,6 @@ import { MigrationContext } from '../../models/migrationLocalStorage';
|
||||
import { sendSqlMigrationActionEvent, TelemetryAction, TelemetryViews } from '../../telemtery';
|
||||
import * as constants from '../../constants/strings';
|
||||
|
||||
export enum MigrationStatus {
|
||||
Failed = 'Failed',
|
||||
Succeeded = 'Succeeded',
|
||||
InProgress = 'InProgress',
|
||||
Canceled = 'Canceled'
|
||||
}
|
||||
|
||||
export class MigrationCutoverDialogModel {
|
||||
|
||||
public migrationStatus!: DatabaseMigration;
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { IconPathHelper } from '../../constants/iconPathHelper';
|
||||
import { MigrationContext, MigrationLocalStorage } from '../../models/migrationLocalStorage';
|
||||
import { MigrationContext, MigrationLocalStorage, MigrationStatus, ProvisioningState } from '../../models/migrationLocalStorage';
|
||||
import { MigrationCutoverDialog } from '../migrationCutover/migrationCutoverDialog';
|
||||
import { AdsMigrationStatus, MigrationStatusDialogModel } from './migrationStatusDialogModel';
|
||||
import * as loc from '../../constants/strings';
|
||||
import { convertTimeDifferenceToDuration, filterMigrations, getMigrationStatusImage, SupportedAutoRefreshIntervals } from '../../api/utils';
|
||||
import { clearDialogMessage, convertTimeDifferenceToDuration, filterMigrations, getMigrationStatusImage, SupportedAutoRefreshIntervals } from '../../api/utils';
|
||||
import { SqlMigrationServiceDetailsDialog } from '../sqlMigrationService/sqlMigrationServiceDetailsDialog';
|
||||
import { ConfirmCutoverDialog } from '../migrationCutover/confirmCutoverDialog';
|
||||
import { MigrationCutoverDialogModel } from '../migrationCutover/migrationCutoverDialogModel';
|
||||
@@ -96,8 +96,15 @@ export class MigrationStatusDialog {
|
||||
azdata.window.openDialog(this._dialogObject);
|
||||
}
|
||||
|
||||
private canCancelMigration = (status: string | undefined) => status && status in ['InProgress', 'Creating', 'Completing', 'Creating'];
|
||||
private canCutoverMigration = (status: string | undefined) => status === 'InProgress';
|
||||
private canCancelMigration = (status: string | undefined) => status &&
|
||||
(
|
||||
status === MigrationStatus.InProgress ||
|
||||
status === MigrationStatus.Creating ||
|
||||
status === MigrationStatus.Completing ||
|
||||
status === MigrationStatus.Canceling
|
||||
);
|
||||
|
||||
private canCutoverMigration = (status: string | undefined) => status === MigrationStatus.InProgress;
|
||||
|
||||
private createSearchAndRefreshContainer(): azdata.FlexContainer {
|
||||
this._searchBox = this._view.modelBuilder.inputBox().withProps({
|
||||
@@ -177,6 +184,7 @@ export class MigrationStatusDialog {
|
||||
'sqlmigration.cutover',
|
||||
async (migrationId: string) => {
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
const migration = this._model._migrations.find(migration => migration.migrationContext.id === migrationId);
|
||||
if (this.canCutoverMigration(migration?.migrationContext.properties.migrationStatus)) {
|
||||
const cutoverDialogModel = new MigrationCutoverDialogModel(migration!);
|
||||
@@ -187,6 +195,12 @@ export class MigrationStatusDialog {
|
||||
await vscode.window.showInformationMessage(loc.MIGRATION_CANNOT_CUTOVER);
|
||||
}
|
||||
} catch (e) {
|
||||
this._dialogObject.message = {
|
||||
text: loc.MIGRATION_STATUS_REFRESH_ERROR,
|
||||
description: e.message,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
|
||||
console.log(e);
|
||||
}
|
||||
}));
|
||||
@@ -231,6 +245,7 @@ export class MigrationStatusDialog {
|
||||
'sqlmigration.copy.migration',
|
||||
async (migrationId: string) => {
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
const migration = this._model._migrations.find(migration => migration.migrationContext.id === migrationId);
|
||||
const cutoverDialogModel = new MigrationCutoverDialogModel(migration!);
|
||||
await cutoverDialogModel.fetchStatus();
|
||||
@@ -245,6 +260,12 @@ export class MigrationStatusDialog {
|
||||
|
||||
await vscode.window.showInformationMessage(loc.DETAILS_COPIED);
|
||||
} catch (e) {
|
||||
this._dialogObject.message = {
|
||||
text: loc.MIGRATION_STATUS_REFRESH_ERROR,
|
||||
description: e.message,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
|
||||
console.log(e);
|
||||
}
|
||||
}));
|
||||
@@ -253,6 +274,7 @@ export class MigrationStatusDialog {
|
||||
'sqlmigration.cancel.migration',
|
||||
async (migrationId: string) => {
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
const migration = this._model._migrations.find(migration => migration.migrationContext.id === migrationId);
|
||||
if (this.canCancelMigration(migration?.migrationContext.properties.migrationStatus)) {
|
||||
vscode.window.showInformationMessage(loc.CANCEL_MIGRATION_CONFIRMATION, loc.YES, loc.NO).then(async (v) => {
|
||||
@@ -266,6 +288,12 @@ export class MigrationStatusDialog {
|
||||
await vscode.window.showInformationMessage(loc.MIGRATION_CANNOT_CANCEL);
|
||||
}
|
||||
} catch (e) {
|
||||
this._dialogObject.message = {
|
||||
text: loc.MIGRATION_CANCELLATION_ERROR,
|
||||
description: e.message,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
|
||||
console.log(e);
|
||||
}
|
||||
}));
|
||||
@@ -371,7 +399,7 @@ export class MigrationStatusDialog {
|
||||
}
|
||||
|
||||
private _getMigrationMode(migration: MigrationContext): string {
|
||||
if (migration.migrationContext.properties.provisioningState === 'Creating') {
|
||||
if (migration.migrationContext.properties.provisioningState === ProvisioningState.Creating) {
|
||||
return '---';
|
||||
}
|
||||
return migration.migrationContext.properties.autoCutoverConfiguration?.autoCutover?.valueOf() ? loc.OFFLINE : loc.ONLINE;
|
||||
@@ -466,11 +494,18 @@ export class MigrationStatusDialog {
|
||||
|
||||
this.isRefreshing = true;
|
||||
try {
|
||||
clearDialogMessage(this._dialogObject);
|
||||
this._refreshLoader.loading = true;
|
||||
const currentConnection = await azdata.connection.getCurrentConnection();
|
||||
this._model._migrations = await MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection, true);
|
||||
await this.populateMigrationTable();
|
||||
} catch (e) {
|
||||
this._dialogObject.message = {
|
||||
text: loc.MIGRATION_STATUS_REFRESH_ERROR,
|
||||
description: e.message,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.isRefreshing = false;
|
||||
@@ -583,13 +618,10 @@ export class MigrationStatusDialog {
|
||||
}
|
||||
|
||||
private _statusInfoMap(status: string): azdata.IconPath {
|
||||
switch (status) {
|
||||
case 'InProgress':
|
||||
case 'Creating':
|
||||
case 'Completing':
|
||||
return IconPathHelper.warning;
|
||||
default:
|
||||
return IconPathHelper.error;
|
||||
}
|
||||
return status === MigrationStatus.InProgress
|
||||
|| status === MigrationStatus.Creating
|
||||
|| status === MigrationStatus.Completing
|
||||
? IconPathHelper.warning
|
||||
: IconPathHelper.error;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user