Improvements in blob storage support for SQL Migration. (#15693)

* changing the cutover icon on migration cutover page.

* Fixing monitoring table and pending log backups

* converting file upload times in utc to local time zones

* adding autorefresh to dashboard, migration status and cutover dialogs.

* Supporting blob container e2e

* vbump extension

* Fixing some PR comments

* Fixed broken blob container dropdown onChange event

* Localizing display string in refresh dialog
Fixing some localized strings

* Fixing var declaration

* making a class readonly for 250px width

* removing refresh interval dialog and replacing it with hardcoded values.

* Fixing summary page IR information.

* surfacing test connection error

* Clearing intervals on view closed to remove auto refresh.
This commit is contained in:
Aasim Khan
2021-06-17 22:19:42 -07:00
committed by GitHub
parent 35832e83da
commit 488ccea731
16 changed files with 458 additions and 228 deletions

View File

@@ -7,6 +7,7 @@ import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as azurecore from 'azurecore';
import { azureResource } from 'azureResource';
import * as constants from '../constants/strings';
async function getAzureCoreAPI(): Promise<azurecore.IExtension> {
const api = (await vscode.extensions.getExtension(azurecore.extension.name)?.activate()) as azurecore.IExtension;
@@ -159,6 +160,22 @@ export async function createSqlMigrationService(account: azdata.Account, subscri
if (response.errors.length > 0) {
throw new Error(response.errors.toString());
}
const asyncUrl = response.response.headers['azure-asyncoperation'];
const maxRetry = 5;
let i = 0;
for (i = 0; i < maxRetry; i++) {
const asyncResponse = await api.makeAzureRestRequest(account, subscription, asyncUrl.replace('https://management.azure.com/', ''), azurecore.HttpRequestMethod.GET, undefined, true);
const creationStatus = asyncResponse.response.data.status;
if (creationStatus === 'Succeeded') {
break;
} else if (creationStatus === 'Failed') {
throw new Error(asyncResponse.errors.toString());
}
await new Promise(resolve => setTimeout(resolve, 3000)); //adding 3 sec delay before getting creation status
}
if (i === maxRetry) {
throw new Error(constants.DMS_PROVISIONING_FAILED);
}
return response.response.data;
}
@@ -426,6 +443,8 @@ export interface MigrationStatusDetails {
fileUploadBlockingErrors: string[];
currentRestoringFileName: string;
lastRestoredFilename: string;
pendingLogBackupsCount: number;
invalidFiles: string[];
}
export interface SqlConnectionInfo {
@@ -462,6 +481,8 @@ export interface BackupSetInfo {
isBackupRestored: boolean;
backupSize: number;
compressedBackupSize: number;
hasBackupChecksums: boolean;
familyCount: number;
}
export interface SourceLocation {
@@ -477,6 +498,12 @@ export interface TargetLocation {
export interface BackupFileInfo {
fileName: string;
status: 'Arrived' | 'Uploading' | 'Uploaded' | 'Restoring' | 'Restored' | 'Cancelled' | 'Ignored';
totalSize: number;
dataRead: number;
dataWritten: number;
copyThroughput: number;
copyDuration: number;
familySequenceNumber: number;
}
export interface DatabaseMigrationFileShare {

View File

@@ -122,6 +122,25 @@ export function filterMigrations(databaseMigrations: MigrationContext[], statusF
return filteredMigration;
}
export function convertByteSizeToReadableUnit(size: number): string {
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
for (let i = 1; i < units.length; i++) {
const higherUnit = size / 1024;
if (higherUnit < 0.1) {
return `${size.toFixed(2)} ${units[i - 1]}`;
}
size = higherUnit;
}
return size.toString();
}
export function convertIsoTimeToLocalTime(isoTime: string): Date {
let isoDate = new Date(isoTime);
return new Date(isoDate.getTime() + (isoDate.getTimezoneOffset() * 60000));
}
export type SupportedAutoRefreshIntervals = -1 | 15000 | 30000 | 60000 | 180000 | 300000;
export function selectDropDownIndex(dropDown: DropDownComponent, index: number): void {
if (index >= 0 && dropDown.values && index <= dropDown.values.length - 1) {
const value = dropDown.values[index];