public static string MakePage(string targetRegion, RegionInfo regionInfo, ServiceParityResult parityResult, CostEstimationResult costEstimationResult) { StringBuilder sb = new StringBuilder(); using (HtmlTextWriter w = new HtmlTextWriter(new StringWriter(sb, CultureInfo.CurrentCulture))) { #region Html w.AddAttribute("lang", "en"); w.RenderBeginTag(HtmlTextWriterTag.Html); MakeHead(w); MakeBody(w, targetRegion, regionInfo, parityResult, costEstimationResult); w.RenderEndTag(); #endregion Html } string html = sb.ToString(); return(html); }
public async Task <string> CreateReportAsync( ServiceParityResult parityResult, CostEstimationResult costEstimationResult) { var targetRegion = costEstimationResult.TargetRegion; var regionInfo = await GetRegionInfoAsync(targetRegion); // Create a MigraDoc document and initialize the page setting var documentInfo = new DocumentInfo(); // Introduction Section var introSection = documentInfo.CreateIntroSection(); // Migration Summary Section CreateMigrationSummarySection( ref documentInfo, regionInfo, costEstimationResult, parityResult); // Service Parity Result CreateAppendixServiceParityResultSection( ref documentInfo, parityResult, costEstimationResult); // TODO: extract common parameters for creating section var needCostEstimation = !costEstimationResult.Details.All(d => d.EstimatedCost == null) || costEstimationResult.HasError; if (needCostEstimation) { // Cost Estimation Section CreateCostEstimationSection( ref documentInfo, regionInfo, costEstimationResult); } // Appendix Full Resource List CreateAppendixResouceListSection( ref documentInfo, regionInfo, costEstimationResult); // Conclusion Section documentInfo.CreateConclusionSection(); // Making TOC AppendTOCToIntroductionSection( ref introSection, costEstimationResult.SubscriptionName, needCostEstimation); return(documentInfo.MakePDF()); }
private static void MakeAssessmentSummary(HtmlTextWriter w, RegionInfo regionInfo, CostEstimationResult costEstimationResult, ServiceParityResult serviceParityResult) { MakeHeader(w, "AssessmentSummary for " + costEstimationResult.SubscriptionName, "AssessmentSummary"); MakeParagraph(w, "Based on user selection and configuration, here is summary about subscription CHN;TST;SHARED;0002:"); MakeAssessmentSummaryTable(w, regionInfo, costEstimationResult, serviceParityResult); }
private static void MakeAssessmentSummaryTable(HtmlTextWriter w, RegionInfo regionInfo, CostEstimationResult costEstimationResult, ServiceParityResult serviceParityResult) { var subscriptionName = costEstimationResult.SubscriptionName; var resourceGroupsCount = costEstimationResult.ResourceGroupsCount; var resourcesCount = costEstimationResult.ResourcesCount; #region Table w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered"); w.RenderBeginTag(HtmlTextWriterTag.Table); #region Tbody w.RenderBeginTag(HtmlTextWriterTag.Tbody); #region Reference Environment MakeKeyValueRow(w, "Reference Environment", "Microsoft Azure"); #endregion Reference Environment #region Reference Subscription MakeKeyValueRow(w, "Reference Subscription", subscriptionName); #endregion Reference Subscription #region Target Environment MakeKeyValueRow(w, "Target Environment", regionInfo.TargetRegionName); #endregion Target Environment #region Number of Resource Group MakeKeyValueRow(w, "Number of Resource Group", resourceGroupsCount.ToString(CultureInfo.InvariantCulture)); #endregion Number of Resource Group #region Number of Resources MakeKeyValueRow(w, "Number of Resources", resourcesCount.ToString(CultureInfo.InvariantCulture)); #endregion Number of Resources #region Number of Resources Failed in Parity Rule Check/Number of All Resources var detailPassFailed = serviceParityResult.Details.Where(d => !d.Value.Pass); var resourceNotPassedCount = costEstimationResult.Details.Where(c => detailPassFailed.Any(d => d.Key == c.ResourceId)).GroupBy(g => g.ResourceId).Count(); MakeKeyValueRow(w, "Number of Resources Failed in Parity Rule Check/Number of All Resources", FormattableString.Invariant($"{resourceNotPassedCount}/{resourcesCount}")); #endregion Number of Resources Failed in Parity Rule Check/Number of All Resources #region Target Region MakeKeyValueRow(w, "Target Region", costEstimationResult.TargetRegion); #endregion Target Region w.RenderEndTag(); #endregion Tbody w.RenderEndTag(); #endregion Table }
public async Task <AssessmentReport> ProcessAsync( ServiceParityResult serviceParityResult, CostEstimationResult costEstimationResult) { //IReportGenerator reportGenerator = new PdfReportGenerator(); IReportGenerator reportGenerator = new HtmlReportGenerator(); AssessmentReport report = await reportGenerator.ProcessAsync( this.context, serviceParityResult, costEstimationResult); return(report); }
// TODO: split code file public async Task <AssessmentReport> ProcessAsync( IAssessmentContext context, ServiceParityResult serviceParityResult, CostEstimationResult costEstimationResult) { var reportFilePath = await this.CreateReportAsync( serviceParityResult, costEstimationResult); return(new AssessmentReport { ReportFilePath = reportFilePath }); }
private static void MakeServiceParity(HtmlTextWriter w, ServiceParityResult serviceParityResult, CostEstimationResult costEstimationResult) { MakeHeader(w, "Service Parity", "ServiceParity"); if (serviceParityResult.Pass) { MakeParagraph(w, "There is no service failed in the parity rule check regarding this migration & expansion"); } else { MakeParagraph(w, "Below are the summary of all services failed in the parity rule check regarding this migration & expansion:"); } MakeSeviceParityTable(w, serviceParityResult, costEstimationResult); }
public async Task <string> CreateReportAsync( ServiceParityResult parityResult, CostEstimationResult costEstimationResult) { var targetRegion = costEstimationResult.TargetRegion; var regionInfo = await GetRegionInfoAsync(targetRegion); var htmlReport = MakePage(targetRegion, regionInfo, parityResult, costEstimationResult); var filename = "CCMEAssessmentReport" + DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + ".html"; var path = Path.Combine(Path.GetTempPath(), filename); Debug.WriteLine(FormattableString.Invariant($"Save PDF document to: {path}")); File.WriteAllText(path, htmlReport); return(path); }
private static void MakeBody(HtmlTextWriter w, string targetRegion, RegionInfo regionInfo, ServiceParityResult parityResult, CostEstimationResult costEstimationResult) { var needCostEstimation = !costEstimationResult.Details.All(d => d.EstimatedCost == null) || costEstimationResult.HasError; #region Body w.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "medium"); w.RenderBeginTag(HtmlTextWriterTag.Body); w.AddAttribute(HtmlTextWriterAttribute.Class, "container"); w.RenderBeginTag(HtmlTextWriterTag.Div); MakeIntroduction(w); MakeTableOfContent(w, costEstimationResult.SubscriptionName, needCostEstimation); MakeAssessmentSummary(w, regionInfo, costEstimationResult, parityResult); MakeServiceParity(w, parityResult, costEstimationResult); if (needCostEstimation) { MakeCostEstimation(w, regionInfo, costEstimationResult); } MakeFullResourceList(w, regionInfo, costEstimationResult); MakeConclusion(w); w.RenderEndTag(); w.RenderEndTag(); #endregion Body }
private static Section CreateAppendixServiceParityResultSection( ref DocumentInfo documentInfo, ServiceParityResult serviceParityResult, CostEstimationResult costEstimationResult) { // TODO: extract to extension method // TODO: move hard code string to resource file var appendixServiceParityResultSection = documentInfo.CreateSection(); var appendixServiceParityResultTitle = appendixServiceParityResultSection.AddParagraph("Service Parity", DocumentInfo.TitleStyleName); appendixServiceParityResultTitle.AddBookmark("ServiceParity"); // All parities if (serviceParityResult.Pass) { appendixServiceParityResultSection.AddParagraph( "There is no service failed in the parity rule check regarding this migration & expansion", DocumentInfo.TableDesStyleName); } else { appendixServiceParityResultSection.AddParagraph( "Below are the summary of all services failed in the parity rule check regarding this migration & expansion: ", DocumentInfo.TableDesStyleName); var detailsAll = serviceParityResult.Details.Where(d => d.Value.Pass == false).ToDictionary(i => i.Key, i => i.Value); // Group up parities by resource group foreach (var resourceGroup in costEstimationResult.DetailsByResourceGroup) { // ResourceGroup.Key is the name of the group if (resourceGroup.Value.Where(r => detailsAll.Keys.Contains(r.ResourceId)).Count() != 0) { var resourceGroupName = resourceGroup.Key; var groupNameTxt = appendixServiceParityResultSection.AddParagraph( "Resource Group: " + resourceGroupName, DocumentInfo.TableDesStyleName); } var parityTable = DocumentInfo.CreateTable(ref appendixServiceParityResultSection); parityTable.AddColumn("4cm"); // Rule name parityTable.AddColumn("2cm"); // Pass parityTable.AddColumn("12cm"); // Message // Check each resource in the group foreach (var resource in resourceGroup.Value) { if (detailsAll.Keys.Contains(resource.ResourceId) && detailsAll[resource.ResourceId].Pass == false) { // Resource name var parityResourceName = parityTable.AddRow(); parityResourceName.Cells[0].AddParagraph("Resource Name"); parityResourceName.Cells[0].Format.Font.Bold = true; parityResourceName.Cells[1].MergeRight = 1; parityResourceName.Cells[1].Column.Width = "14.5cm"; documentInfo.AddParagraphWordWrap(parityResourceName.Cells[1], resource.ResourceName); // Resource Id var parityResourceID = parityTable.AddRow(); parityResourceID.Cells[0].AddParagraph("Resource ID"); parityResourceID.Cells[0].Format.Font.Bold = true; parityResourceID.Cells[1].MergeRight = 1; parityResourceID.Cells[1].Column.Width = "14.5cm"; var cutMark = "providers"; var cut = resource.ResourceId.IndexOf(cutMark, StringComparison.OrdinalIgnoreCase) + cutMark.Length; var resourceID = cut == -1 ? resource.ResourceId : resource.ResourceId.Substring(cut, resource.ResourceId.Length - cut); documentInfo.AddParagraphWordWrap(parityResourceID.Cells[1], resourceID); var parityProperties = parityTable.AddRow(); parityResourceID.Cells[1].Column.Width = "2cm"; parityProperties.Format.Font.Bold = true; parityProperties.Cells[0].AddParagraph("RuleName"); parityProperties.Cells[1].AddParagraph("Pass"); parityProperties.Cells[2].AddParagraph("Message"); // Check each parity result for the resource foreach (var ruleCheck in detailsAll[resource.ResourceId].Details.Where(d => d.Pass == false)) { var ruleCheckRow = parityTable.AddRow(); documentInfo.AddParagraphWordWrap(ruleCheckRow.Cells[0], ruleCheck.Brief); documentInfo.AddParagraphWordWrap(ruleCheckRow.Cells[1], "N"); documentInfo.AddParagraphWordWrap(ruleCheckRow.Cells[2], ruleCheck.Message); } } } } } return(appendixServiceParityResultSection); }
private static Section CreateMigrationSummarySection( ref DocumentInfo documentInfo, RegionInfo regionInfo, CostEstimationResult costEstimationResult, ServiceParityResult serviceParityResult) { // TODO: extract to extension method // TODO: move hard code string to resource file var subscriptionName = costEstimationResult.SubscriptionName; var resourceGroupsCount = costEstimationResult.ResourceGroupsCount; var resourcesCount = costEstimationResult.ResourcesCount; var migrationSummarySection = documentInfo.CreateSection(); var summaryTitle = migrationSummarySection.AddParagraph( "Assessment Summary for " + subscriptionName, DocumentInfo.TitleStyleName); summaryTitle.AddBookmark("MigrationSummary" + subscriptionName); migrationSummarySection.AddParagraph( "Based on user selection and configuration, here is summary about subscription " + subscriptionName + ":", DocumentInfo.TableDesStyleName); var shortSummary = DocumentInfo.CreateTable(ref migrationSummarySection); var summaryTitleColumn = shortSummary.AddColumn("8cm"); summaryTitleColumn.Format.Font = DocumentInfo.ContentFontBold.Clone(); shortSummary.AddColumn("8cm"); var shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Reference Environment"); shortSummaryRow.Cells[1].AddParagraph("Microsoft Azure"); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Reference Subscription"); documentInfo.AddParagraphWordWrap(shortSummaryRow.Cells[1], subscriptionName); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Target Environment"); shortSummaryRow.Cells[1].AddParagraph(regionInfo.TargetRegionName); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Number of Resource Group"); shortSummaryRow.Cells[1].AddParagraph(resourceGroupsCount.ToString(CultureInfo.InvariantCulture)); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Number of Resources"); shortSummaryRow.Cells[1].AddParagraph(resourcesCount.ToString(CultureInfo.InvariantCulture)); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Number of Resources Failed in Parity Rule Check/Number of All Resources"); var detailPassFailed = serviceParityResult.Details.Where(d => !d.Value.Pass); var resourceNotPassedCount = costEstimationResult.Details.Where(c => detailPassFailed.Any(d => d.Key == c.ResourceId)).GroupBy(g => g.ResourceId).Count(); shortSummaryRow.Cells[1].AddParagraph(FormattableString.Invariant($"{resourceNotPassedCount}/{resourcesCount}")); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Target Region"); shortSummaryRow.Cells[1].AddParagraph(costEstimationResult.TargetRegion); return(migrationSummarySection); }
private static void MakeSeviceParityTable(HtmlTextWriter w, ServiceParityResult serviceParityResult, CostEstimationResult costEstimationResult) { var detailsAll = serviceParityResult.Details.Where(d => d.Value.Pass == false).ToDictionary(i => i.Key, i => i.Value); // Group up parities by resource group foreach (var resourceGroup in costEstimationResult.DetailsByResourceGroup) { // ResourceGroup.Key is the name of the group if (resourceGroup.Value.Where(r => detailsAll.Keys.Contains(r.ResourceId)).Count() != 0) { var resourceGroupName = resourceGroup.Key; MakeParagraph(w, "Resource Group: " + resourceGroupName); } // Check each resource in the group foreach (var resource in resourceGroup.Value) { if (detailsAll.Keys.Contains(resource.ResourceId) && detailsAll[resource.ResourceId].Pass == false) { #region Table w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered"); w.RenderBeginTag(HtmlTextWriterTag.Table); #region Tbody w.RenderBeginTag(HtmlTextWriterTag.Tbody); #region Resource Name w.RenderBeginTag(HtmlTextWriterTag.Tr); w.AddAttribute(HtmlTextWriterAttribute.Scope, "row"); w.RenderBeginTag(HtmlTextWriterTag.Th); w.Write("Resource Name"); w.RenderEndTag(); w.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); w.RenderBeginTag(HtmlTextWriterTag.Td); w.Write(resource.ResourceName); w.RenderEndTag(); w.RenderEndTag(); #endregion Resource Name #region Resource Id var cutMark = "providers"; var cut = resource.ResourceId.IndexOf(cutMark, StringComparison.OrdinalIgnoreCase) + cutMark.Length; var resourceID = cut == -1 ? resource.ResourceId : resource.ResourceId.Substring(cut, resource.ResourceId.Length - cut); w.RenderBeginTag(HtmlTextWriterTag.Tr); w.AddAttribute(HtmlTextWriterAttribute.Scope, "row"); w.RenderBeginTag(HtmlTextWriterTag.Th); w.Write("Resource Id"); w.RenderEndTag(); w.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); w.RenderBeginTag(HtmlTextWriterTag.Td); w.Write(resourceID); w.RenderEndTag(); w.RenderEndTag(); #endregion Resource Id #region Head for RuleName Pass Message w.RenderBeginTag(HtmlTextWriterTag.Tr); w.AddAttribute(HtmlTextWriterAttribute.Style, "width:30%"); w.AddAttribute(HtmlTextWriterAttribute.Scope, "col"); w.RenderBeginTag(HtmlTextWriterTag.Th); w.Write("RuleName"); w.RenderEndTag(); w.AddAttribute(HtmlTextWriterAttribute.Style, "width:15%"); w.AddAttribute(HtmlTextWriterAttribute.Scope, "col"); w.RenderBeginTag(HtmlTextWriterTag.Th); w.Write("Pass"); w.RenderEndTag(); w.AddAttribute(HtmlTextWriterAttribute.Style, "width:55%"); w.AddAttribute(HtmlTextWriterAttribute.Scope, "col"); w.RenderBeginTag(HtmlTextWriterTag.Th); w.Write("Message"); w.RenderEndTag(); w.RenderEndTag(); #endregion Head for RuleName Pass Message #region Data for RuleName Pass Message foreach (var ruleCheck in detailsAll[resource.ResourceId].Details.Where(d => d.Pass == false)) { w.RenderBeginTag(HtmlTextWriterTag.Tr); w.RenderBeginTag(HtmlTextWriterTag.Td); w.Write(ruleCheck.Brief); w.RenderEndTag(); w.RenderBeginTag(HtmlTextWriterTag.Td); w.Write("N"); w.RenderEndTag(); w.RenderBeginTag(HtmlTextWriterTag.Td); w.Write(ruleCheck.Message); w.RenderEndTag(); w.RenderEndTag(); } #endregion Data for RuleName Pass Message w.RenderEndTag(); #endregion Tbody w.RenderEndTag(); #endregion Table } } } }