/// <summary> /// Initializes a new instance of the <see cref="SmartSignalResultItemPresentation"/> class /// </summary> /// <param name="id">The result item ID</param> /// <param name="title">The result item title</param> /// <param name="summary">The result item summary</param> /// <param name="resourceId">The result item resource ID</param> /// <param name="correlationHash">The result item correlation hash</param> /// <param name="signalId">The signal ID</param> /// <param name="signalName">The signal name</param> /// <param name="analysisTimestamp">The end time of the analysis window</param> /// <param name="analysisWindowSizeInMinutes">The analysis window size (in minutes)</param> /// <param name="properties">The result item properties</param> /// <param name="rawProperties">The raw result item properties</param> /// <param name="queryRunInfo">The query run information</param> public SmartSignalResultItemPresentation( string id, string title, SmartSignalResultItemPresentationSummary summary, string resourceId, string correlationHash, string signalId, string signalName, DateTime analysisTimestamp, int analysisWindowSizeInMinutes, List <SmartSignalResultItemPresentationProperty> properties, IReadOnlyDictionary <string, string> rawProperties, SmartSignalResultItemQueryRunInfo queryRunInfo) { this.Id = id; this.Title = title; this.Summary = summary; this.ResourceId = resourceId; this.CorrelationHash = correlationHash; this.SignalId = signalId; this.SignalName = signalName; this.AnalysisTimestamp = analysisTimestamp; this.AnalysisWindowSizeInMinutes = analysisWindowSizeInMinutes; this.Properties = properties; this.RawProperties = rawProperties; this.QueryRunInfo = queryRunInfo; }
/// <summary> /// Creates a presentation from a result item /// </summary> /// <param name="request">The smart signal request</param> /// <param name="signalName">The signal name</param> /// <param name="smartSignalResultItem">The result item</param> /// <param name="queryRunInfo">The query run information</param> /// <returns>The presentation</returns> public static SmartSignalResultItemPresentation CreateFromResultItem(SmartSignalRequest request, string signalName, SmartSignalResultItem smartSignalResultItem, SmartSignalResultItemQueryRunInfo queryRunInfo) { // A null result item has null presentation if (smartSignalResultItem == null) { return(null); } // Create presentation elements for each result item property Dictionary <string, string> predicates = new Dictionary <string, string>(); List <SmartSignalResultItemPresentationProperty> presentationProperties = new List <SmartSignalResultItemPresentationProperty>(); SmartSignalResultItemPresentationProperty summaryChart = null; string summaryValue = null; string summaryDetails = null; Dictionary <string, string> rawProperties = new Dictionary <string, string>(); foreach (PropertyInfo property in smartSignalResultItem.GetType().GetProperties()) { // Get the property value string propertyValue = PropertyValueToString(property.GetValue(smartSignalResultItem)); rawProperties[property.Name] = propertyValue; // Check if this property is a predicate if (property.GetCustomAttribute <ResultItemPredicateAttribute>() != null) { predicates[property.Name] = propertyValue; } // Get the presentation attribute ResultItemPresentationAttribute attribute = property.GetCustomAttribute <ResultItemPresentationAttribute>(); if (attribute != null) { // Verify that if the entity is a chart or query, then query run information was provided if (queryRunInfo == null && (attribute.Section == ResultItemPresentationSection.Chart || attribute.Section == ResultItemPresentationSection.AdditionalQuery)) { throw new InvalidSmartSignalResultItemPresentationException($"The presentation contains an item for the {attribute.Section} section, but no telemetry data client was provided"); } // Get the attribute title and information balloon - support interpolated strings string attributeTitle = Smart.Format(attribute.Title, smartSignalResultItem); string attributeInfoBalloon = Smart.Format(attribute.InfoBalloon, smartSignalResultItem); // Add presentation to the summary component if (attribute.Component.HasFlag(ResultItemPresentationComponent.Summary)) { if (attribute.Section == ResultItemPresentationSection.Chart) { // Verify there is at most one summary chart if (summaryChart != null) { throw new InvalidSmartSignalResultItemPresentationException("There can be at most one summary chart for each resultItem"); } // Create the summary chart presentation property summaryChart = new SmartSignalResultItemPresentationProperty(attributeTitle, propertyValue, attribute.Section, attributeInfoBalloon); } else if (attribute.Section == ResultItemPresentationSection.Property) { // Verify there is at most one summary presentation property if (summaryValue != null) { throw new InvalidSmartSignalResultItemPresentationException("There must be exactly one summary property for each resultItem"); } // Set summary presentation elements summaryValue = propertyValue; summaryDetails = attributeTitle; } else { throw new InvalidSmartSignalResultItemPresentationException($"Invalid section for summary property {property.Name}: {attribute.Section}"); } } // Add presentation to the details component if (attribute.Component.HasFlag(ResultItemPresentationComponent.Details)) { presentationProperties.Add(new SmartSignalResultItemPresentationProperty(attributeTitle, propertyValue, attribute.Section, attributeInfoBalloon)); } } } // Verify that a summary was provided if (summaryValue == null) { throw new InvalidSmartSignalResultItemPresentationException("There must be exactly one summary property for each result item"); } string id = string.Join("##", smartSignalResultItem.GetType().FullName, JsonConvert.SerializeObject(request), JsonConvert.SerializeObject(smartSignalResultItem)).Hash(); string resourceId = smartSignalResultItem.ResourceIdentifier.ToResourceId(); string correlationHash = string.Join("##", predicates.OrderBy(x => x.Key).Select(x => x.Key + "|" + x.Value)).Hash(); // Return the presentation object return(new SmartSignalResultItemPresentation( id, smartSignalResultItem.Title, new SmartSignalResultItemPresentationSummary(summaryValue, summaryDetails, summaryChart), resourceId, correlationHash, request.SignalId, signalName, DateTime.UtcNow, (int)request.Cadence.TotalMinutes, presentationProperties, rawProperties, queryRunInfo)); }