add assessment error handling and bypass option (#17369)

* add assessment error handling and bypass option

* add desriptive text and results warnings
This commit is contained in:
brian-harris
2021-10-15 15:15:52 -07:00
committed by GitHub
parent 59b43d8c67
commit 2e677dbda6
5 changed files with 195 additions and 90 deletions

View File

@@ -26,6 +26,8 @@ export class SKURecommendationPage extends MigrationWizardPage {
private _igComponent!: azdata.TextComponent;
private _assessmentStatusIcon!: azdata.ImageComponent;
private _detailsComponent!: azdata.TextComponent;
private _skipAssessmentCheckbox!: azdata.CheckBoxComponent;
private _skipAssessmentSubText!: azdata.TextComponent;
private _chooseTargetComponent!: azdata.DivContainer;
private _azureSubscriptionText!: azdata.TextComponent;
private _managedInstanceSubscriptionDropdown!: azdata.DropDownComponent;
@@ -90,6 +92,29 @@ export class SKURecommendationPage extends MigrationWizardPage {
});
this._detailsComponent = this.createDetailsComponent(view); // The details of what can be moved
this._skipAssessmentCheckbox = view.modelBuilder.checkBox().withProps({
label: constants.SKU_RECOMMENDATION_ASSESSMENT_ERROR_BYPASS,
checked: false,
CSSStyles: {
...styles.SECTION_HEADER_CSS,
'margin': '10px 0 0 0',
'display': 'none'
},
}).component();
this._skipAssessmentSubText = view.modelBuilder.text().withProps({
value: constants.SKU_RECOMMENDATION_ASSESSMENT_ERROR_DETAIL,
CSSStyles: {
'margin': '0 0 0 15px',
'font-size': '13px',
'color': 'red',
'width': '590px',
'display': 'none'
},
}).component();
this._disposables.push(this._skipAssessmentCheckbox.onChanged(async (value) => {
await this._setAssessmentState(false, true);
}));
const refreshAssessmentButton = this._view.modelBuilder.button().withProps({
iconPath: IconPathHelper.refresh,
@@ -113,6 +138,8 @@ export class SKURecommendationPage extends MigrationWizardPage {
igContainer,
this._detailsComponent,
refreshAssessmentButton,
this._skipAssessmentCheckbox,
this._skipAssessmentSubText,
]
).withProps({
CSSStyles: {
@@ -501,50 +528,49 @@ export class SKURecommendationPage extends MigrationWizardPage {
text: '',
level: azdata.window.MessageLevel.Error
};
await this._assessmentComponent.updateCssStyles({ display: 'block' });
await this._formContainer.component().updateCssStyles({ display: 'none' });
this._assessmentLoader.loading = true;
await this._setAssessmentState(true, false);
const serverName = (await this.migrationStateModel.getSourceConnectionProfile()).serverName;
this._igComponent.value = constants.ASSESSMENT_COMPLETED(serverName);
const errors: string[] = [];
try {
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage) {
this.migrationStateModel._assessmentResults = <ServerAssessment>this.migrationStateModel.savedInfo.serverAssessment;
} else {
await this.migrationStateModel.getDatabaseAssessments(MigrationTargetType.SQLMI);
}
this._detailsComponent.value = constants.SKU_RECOMMENDATION_ALL_SUCCESSFUL(this.migrationStateModel._assessmentResults.databaseAssessments.length);
const errors: string[] = [];
const assessmentError = this.migrationStateModel._assessmentResults.assessmentError;
if (assessmentError) {
errors.push(`message: ${assessmentError.message}
stack: ${assessmentError.stack}
`);
errors.push(`message: ${assessmentError.message}${EOL}stack: ${assessmentError.stack}`);
}
if (this.migrationStateModel?._assessmentResults?.errors?.length! > 0) {
errors.push(...this.migrationStateModel._assessmentResults.errors?.map(e => `message: ${e.message}
errorSummary: ${e.errorSummary}
possibleCauses: ${e.possibleCauses}
guidance: ${e.guidance}
errorId: ${e.errorId}
`)!);
errors.push(...this.migrationStateModel._assessmentResults.errors?.map(
e => `message: ${e.message}${EOL}errorSummary: ${e.errorSummary}${EOL}possibleCauses: ${e.possibleCauses}${EOL}guidance: ${e.guidance}${EOL}errorId: ${e.errorId}`)!);
}
} catch (e) {
console.log(e);
errors.push(constants.SKU_RECOMMENDATION_ASSESSMENT_UNEXPECTED_ERROR(serverName, e));
} finally {
this.migrationStateModel._runAssessments = errors.length > 0;
if (errors.length > 0) {
this.wizard.message = {
text: constants.SKU_RECOMMENDATION_ASSESSMENT_ERROR(serverName),
description: errors.join(EOL),
level: azdata.window.MessageLevel.Error
};
this._assessmentStatusIcon.iconPath = IconPathHelper.error;
this._igComponent.value = constants.ASSESSMENT_FAILED(serverName);
this._detailsComponent.value = constants.SKU_RECOMMENDATION_ERROR;
} else {
this._assessmentStatusIcon.iconPath = IconPathHelper.completedMigration;
this._igComponent.value = constants.ASSESSMENT_COMPLETED(serverName);
this._detailsComponent.value = constants.SKU_RECOMMENDATION_ALL_SUCCESSFUL(this.migrationStateModel._assessmentResults.databaseAssessments.length);
}
this.migrationStateModel._runAssessments = errors.length > 0;
} catch (e) {
console.log(e);
}
if (this.migrationStateModel.resumeAssessment && this.migrationStateModel.savedInfo.closedPage >= Page.SKURecommendation) {
if ((this.migrationStateModel.resumeAssessment) && this.migrationStateModel.savedInfo.closedPage >= Page.SKURecommendation) {
if (this.migrationStateModel.savedInfo.migrationTargetType) {
this._rbg.selectedCardId = this.migrationStateModel.savedInfo.migrationTargetType;
await this.refreshCardText();
@@ -552,9 +578,39 @@ errorId: ${e.errorId}
}
await this.refreshCardText();
this._assessmentLoader.loading = false;
await this._assessmentComponent.updateCssStyles({ display: 'none' });
await this._formContainer.component().updateCssStyles({ display: 'block' });
await this._setAssessmentState(false, this.migrationStateModel._runAssessments);
}
private async _setAssessmentState(assessing: boolean, failedAssessment: boolean): Promise<void> {
let display: azdata.DisplayType = assessing ? 'block' : 'none';
await this._assessmentComponent.updateCssStyles({ 'display': display });
this._assessmentComponent.display = display;
display = !assessing && failedAssessment ? 'block' : 'none';
await this._skipAssessmentCheckbox.updateCssStyles({ 'display': display });
this._skipAssessmentCheckbox.display = display;
await this._skipAssessmentSubText.updateCssStyles({ 'display': display });
this._skipAssessmentSubText.display = display;
await this._formContainer.component().updateCssStyles({ 'display': !assessing ? 'block' : 'none' });
display = failedAssessment && !this._skipAssessmentCheckbox.checked ? 'none' : 'block';
await this._chooseTargetComponent.updateCssStyles({ 'display': display });
this._chooseTargetComponent.display = display;
display = !this._rbg.selectedCardId || failedAssessment && !this._skipAssessmentCheckbox.checked ? 'none' : 'inline';
await this.assessmentGroupContainer.updateCssStyles({ 'display': display });
this.assessmentGroupContainer.display = display;
display = this._rbg.selectedCardId
&& (!failedAssessment || this._skipAssessmentCheckbox.checked)
&& this.migrationStateModel._migrationDbs.length > 0
? 'inline'
: 'none';
await this._targetContainer.updateCssStyles({ 'display': display });
this._targetContainer.display = display;
this._assessmentLoader.loading = assessing;
}
private async populateSubscriptionDropdown(): Promise<void> {
@@ -698,18 +754,9 @@ errorId: ${e.errorId}
return true;
});
this.wizard.nextButton.enabled = false;
if (this.migrationStateModel._runAssessments) {
await this.constructDetails();
}
await this._assessmentComponent.updateCssStyles({
display: 'none'
});
await this._formContainer.component().updateCssStyles({
display: 'block'
});
await this.constructDetails();
await this.populateSubscriptionDropdown();
this.wizard.nextButton.enabled = true;
this.wizard.nextButton.enabled = this.migrationStateModel._assessmentResults !== undefined;
}
public async onPageLeave(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
@@ -726,15 +773,6 @@ errorId: ${e.errorId}
protected async handleStateChange(e: StateChangeEvent): Promise<void> {
}
public async refreshDatabaseCount(selectedDbs: string[]): Promise<void> {
this.wizard.message = {
text: '',
level: azdata.window.MessageLevel.Error
};
this.migrationStateModel._migrationDbs = selectedDbs;
await this.refreshCardText();
}
public async refreshCardText(): Promise<void> {
this._rbgLoader.loading = true;
if (this._rbg.selectedCardId === MigrationTargetType.SQLMI) {
@@ -747,25 +785,16 @@ errorId: ${e.errorId}
this._targetContainer.display = (this.migrationStateModel._migrationDbs.length === 0) ? 'none' : 'inline';
if (this.migrationStateModel._assessmentResults) {
const dbCount = this.migrationStateModel._assessmentResults.databaseAssessments.length;
const dbCount = this.migrationStateModel._assessmentResults.databaseAssessments?.length;
const dbWithoutIssuesCount = this.migrationStateModel._assessmentResults.databaseAssessments?.filter(db => db.issues?.length === 0).length;
this._rbg.cards[0].descriptions[1].textValue = constants.CAN_BE_MIGRATED(dbWithoutIssuesCount, dbCount);
this._rbg.cards[1].descriptions[1].textValue = constants.CAN_BE_MIGRATED(dbCount, dbCount);
const dbWithoutIssuesCount = this.migrationStateModel._assessmentResults.databaseAssessments.filter(db => db.issues.length === 0).length;
const miCardText = constants.CAN_BE_MIGRATED(dbWithoutIssuesCount, dbCount);
this._rbg.cards[0].descriptions[1].textValue = miCardText;
const vmCardText = constants.CAN_BE_MIGRATED(dbCount, dbCount);
this._rbg.cards[1].descriptions[1].textValue = vmCardText;
await this._rbg.updateProperties({
cards: this._rbg.cards
});
await this._rbg.updateProperties({ cards: this._rbg.cards });
} else {
this._rbg.cards[0].descriptions[1].textValue = '';
this._rbg.cards[1].descriptions[1].textValue = '';
await this._rbg.updateProperties({
cards: this._rbg.cards
});
await this._rbg.updateProperties({ cards: this._rbg.cards });
}
if (this._rbg.selectedCardId) {