diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs index eeae886cf7..18c5a931e4 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; using System.Text.Json; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -30,7 +28,7 @@ public class TelemetrySolutionInfoEnricher : ITelemetryActivityEventEnricher, IS if (await _telemetryActivityStorage.ShouldAddSolutionInformation(solutionId)) { activity[ActivityPropertyNames.SolutionId] = solutionId; - await FillSolutionInfoAsync(activity); + AddSolutionInfo(activity); await _telemetryActivityStorage.MarkSolutionInfoAsAddedAsync(solutionId); activity[ActivityPropertyNames.HasSolutionInfo] = true; activity.Remove(ActivityPropertyNames.SolutionPath); @@ -54,142 +52,105 @@ public class TelemetrySolutionInfoEnricher : ITelemetryActivityEventEnricher, IS return false; } - private Task FillSolutionInfoAsync(ActivityEvent activity) + private void AddSolutionInfo(ActivityEvent activity) { try { - if (!activity.TryGetValue(ActivityPropertyNames.SolutionPath, out var rawSolutionPath) - || string.IsNullOrWhiteSpace(rawSolutionPath?.ToString()) - || !File.Exists(rawSolutionPath?.ToString())) - { - return Task.CompletedTask; - } + var solutionPath = activity[ActivityPropertyNames.SolutionPath]!.ToString()!; - var solutionPath = rawSolutionPath!.ToString()!; var jsonContent = File.ReadAllText(solutionPath); using var doc = JsonDocument.Parse(jsonContent); var root = doc.RootElement; - AddSolutionInformation(activity, root.GetProperty("creatingStudioConfiguration")); + AddSolutionCreationConfiguration(activity, root.GetProperty("creatingStudioConfiguration")); - if (root.TryGetProperty("modules", out var modulesElement) && modulesElement.ValueKind == JsonValueKind.Object) + if (root.TryGetProperty("modules", out var modulesElement) && + modulesElement.ValueKind == JsonValueKind.Object) { - var directoryPath = Path.GetDirectoryName(solutionPath)!; - activity[ActivityPropertyNames.InstalledModules] = ExtractModules(directoryPath, modulesElement); + activity[ActivityPropertyNames.InstalledModules] = ExtractModules(solutionPath, modulesElement); } } catch { // ignored } - - return Task.CompletedTask; } private bool TryGetSolutionIdFromActivity(ActivityEvent activity, out Guid solutionId) { - if (activity.TryGetValue(ActivityPropertyNames.SolutionId, out var value) && Guid.TryParse(value?.ToString(), out var parsedId)) { solutionId = parsedId; return true; } - + solutionId = Guid.Empty; return false; } private bool TryGetSolutionIdFromFile(ActivityEvent activity, out Guid solutionId) { - solutionId = Guid.Empty; - - if (!activity.TryGetValue(ActivityPropertyNames.SolutionPath, out var value)) - { - return false; - } - - var path = value?.ToString(); - if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) - { - return false; - } - - try + if (activity.TryGetValue(ActivityPropertyNames.SolutionPath, out var pathValue) && + pathValue is string && + File.Exists(pathValue.ToString())) { - var json = File.ReadAllText(path); - using var doc = JsonDocument.Parse(json); - if (doc.RootElement.TryGetProperty("id", out var idProp) && - Guid.TryParse(idProp.GetString(), out var parsedId)) + try { - solutionId = parsedId; - return true; + var solutionPath = pathValue.ToString()!; + var json = File.ReadAllText(solutionPath); + using var doc = JsonDocument.Parse(json); + if (doc.RootElement.TryGetProperty("id", out var idProp) && + Guid.TryParse(idProp.GetString(), out var parsedId)) + { + solutionId = parsedId; + return true; + } + } + catch + { + // ignored } } - catch - { - // ignored - } - + + solutionId = Guid.Empty; return false; } - private void AddSolutionInformation(Dictionary activity, JsonElement config) + private void AddSolutionCreationConfiguration(ActivityEvent activity, JsonElement config) { - var map = new (string Key, Action Apply)[] - { - ("template", v => activity[ActivityPropertyNames.Template] = v.GetString() ?? string.Empty), - ("createdAbpStudioVersion", v => activity[ActivityPropertyNames.CreatedAbpStudioVersion] = v.GetString()!), - ("multiTenancy", v => activity[ActivityPropertyNames.MultiTenancy] = ParseBool(v)), - ("uiFramework", v => activity[ActivityPropertyNames.UiFramework] = v.GetString() ?? string.Empty), - ("databaseProvider", v => activity[ActivityPropertyNames.DatabaseProvider] = v.GetString() ?? string.Empty), - ("theme", v => activity[ActivityPropertyNames.Theme] = v.GetString() ?? string.Empty), - ("themeStyle", v => activity[ActivityPropertyNames.ThemeStyle] = v.GetString() ?? string.Empty), - ("publicWebsite", v => activity[ActivityPropertyNames.HasPublicWebsite] = ParseBool(v)), - ("tiered", v => activity[ActivityPropertyNames.IsTiered] = ParseBool(v)), - ("socialLogin", v => activity[ActivityPropertyNames.SocialLogins] = ParseBool(v)), - ("databaseManagementSystem", v => activity[ActivityPropertyNames.DatabaseManagementSystem] = v.GetString() ?? string.Empty), - ("separateTenantSchema", v => activity[ActivityPropertyNames.IsSeparateTenantSchema] = ParseBool(v)), - ("mobileFramework", v => activity[ActivityPropertyNames.MobileFramework] = v.GetString() ?? string.Empty), - ("includeTests", v => activity[ActivityPropertyNames.IncludeTests] = ParseBool(v)), - ("dynamicLocalization", v => activity[ActivityPropertyNames.DynamicLocalization] = ParseBool(v)), - ("kubernetesConfiguration", v => activity[ActivityPropertyNames.KubernetesConfiguration] = ParseBool(v)), - ("grafanaDashboard", v => activity[ActivityPropertyNames.GrafanaDashboard] = ParseBool(v)), - }; - - foreach (var (key, apply) in map) - { - if (config.TryGetProperty(key, out var prop)) - { - apply(prop); - } - } + activity[ActivityPropertyNames.Template] = config.GetProperty("template").GetString() ?? string.Empty; + activity[ActivityPropertyNames.CreatedAbpStudioVersion] = config.GetProperty("createdAbpStudioVersion").GetString()!; + activity[ActivityPropertyNames.MultiTenancy] = ParseBool(config.GetProperty("multiTenancy")); + activity[ActivityPropertyNames.UiFramework] = config.GetProperty("uiFramework").GetString() ?? string.Empty; + activity[ActivityPropertyNames.DatabaseProvider] = config.GetProperty("databaseProvider").GetString() ?? string.Empty; + activity[ActivityPropertyNames.Theme] = config.GetProperty("theme").GetString() ?? string.Empty; + activity[ActivityPropertyNames.ThemeStyle] = config.GetProperty("themeStyle").GetString() ?? string.Empty; + activity[ActivityPropertyNames.HasPublicWebsite] = ParseBool(config.GetProperty("publicWebsite")); + activity[ActivityPropertyNames.IsTiered] = ParseBool(config.GetProperty("tiered")); + activity[ActivityPropertyNames.SocialLogins] = ParseBool(config.GetProperty("socialLogin")); + activity[ActivityPropertyNames.DatabaseManagementSystem] = config.GetProperty("databaseManagementSystem").GetString() ?? string.Empty; + activity[ActivityPropertyNames.IsSeparateTenantSchema] = ParseBool(config.GetProperty("separateTenantSchema")); + activity[ActivityPropertyNames.MobileFramework] = config.GetProperty("mobileFramework").GetString() ?? string.Empty; + activity[ActivityPropertyNames.IncludeTests] = ParseBool(config.GetProperty("includeTests")); + activity[ActivityPropertyNames.DynamicLocalization] = ParseBool(config.GetProperty("dynamicLocalization")); + activity[ActivityPropertyNames.KubernetesConfiguration] = ParseBool(config.GetProperty("kubernetesConfiguration")); + activity[ActivityPropertyNames.GrafanaDashboard] = ParseBool(config.GetProperty("grafanaDashboard")); } - private List> ExtractModules(string directoryPath, JsonElement modulesElement) + private List> ExtractModules(string solutionPath, JsonElement modulesElement) { var modules = new List>(); foreach (var module in modulesElement.EnumerateObject()) { - if (!module.Value.TryGetProperty("path", out var pathElement)) - { - continue; - } - - var path = pathElement.GetString(); - if (string.IsNullOrWhiteSpace(path)) - { - continue; - } - - var fullPath = Path.Combine(directoryPath, path); - if (!File.Exists(fullPath)) + var modulePath = GetModuleFilePath(solutionPath, module); + if (modulePath.IsNullOrEmpty()) { continue; } - var moduleJson = File.ReadAllText(fullPath); + var moduleJson = File.ReadAllText(modulePath); using var moduleDoc = JsonDocument.Parse(moduleJson); if (!moduleDoc.RootElement.TryGetProperty("imports", out var imports) || @@ -201,6 +162,7 @@ public class TelemetrySolutionInfoEnricher : ITelemetryActivityEventEnricher, IS foreach (var import in imports.EnumerateObject()) { var version = import.Value.GetProperty("version").GetString(); + var creationTime = import.Value.TryGetProperty("creationTime", out var ct) ? DateTimeOffset.Parse(ct.GetString()!) : (DateTimeOffset?)null; @@ -230,6 +192,23 @@ public class TelemetrySolutionInfoEnricher : ITelemetryActivityEventEnricher, IS return modules; } + private string? GetModuleFilePath(string solutionPath, JsonProperty module) + { + if (!module.Value.TryGetProperty("path", out var pathElement)) + { + return null; + } + + var path = pathElement.GetString(); + if (path.IsNullOrEmpty()) + { + return null; + } + + var fullPath = Path.Combine(Path.GetDirectoryName(solutionPath)!, path); + return File.Exists(fullPath) ? fullPath : null; + } + private bool ParseBool(JsonElement element) { return element.ValueKind switch