From 0378c29da5419f71f95ad01e15a412d5b0d71f09 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Thu, 19 Feb 2026 10:08:48 +0100 Subject: [PATCH] Keep track of the config env id to show a mismatch --- .../Pages/Information.razor | 61 +++++++++++++------ .../Pages/Information.razor.cs | 26 +++++++- .../Tools/PluginSystem/IAvailablePlugin.cs | 3 + .../PluginSystem/PluginFactory.Loading.cs | 15 +++-- .../Tools/PluginSystem/PluginMetadata.cs | 4 +- 5 files changed, 84 insertions(+), 25 deletions(-) diff --git a/app/MindWork AI Studio/Pages/Information.razor b/app/MindWork AI Studio/Pages/Information.razor index 5a964179..7e24d94b 100644 --- a/app/MindWork AI Studio/Pages/Information.razor +++ b/app/MindWork AI Studio/Pages/Information.razor @@ -137,25 +137,46 @@ break; case true: - - @T("AI Studio runs with an enterprise configuration and configuration servers. The configuration plugins are active.") - + @if (this.HasAnyLoadedEnterpriseConfigurationPlugin) + { + + @T("AI Studio runs with an enterprise configuration and configuration servers. The configuration plugins are active.") + + } + else + { + + @T("AI Studio runs with an enterprise configuration and configuration servers. The configuration plugins are not yet available.") + + } @foreach (var env in EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.Where(e => e.IsActive)) { - var matchingPlugin = this.configPlugins.FirstOrDefault(p => p.Id == env.ConfigurationId); + var matchingPlugin = this.FindManagedConfigurationPlugin(env.ConfigurationId); + if (matchingPlugin is null) + { + +
+ + @T("Waiting for the configuration plugin...") +
+
+ + @T("Enterprise configuration ID:") @env.ConfigurationId + +
+
+ + @T("Configuration server:") @env.ConfigurationServerUrl + +
+
+ continue; + }
- @if (matchingPlugin is not null) - { - - @matchingPlugin.Name - } - else - { - - @T("ID mismatch: the plugin ID differs from the enterprise configuration ID.") - } + + @matchingPlugin.Name
@@ -167,12 +188,16 @@ @T("Configuration server:") @env.ConfigurationServerUrl
- @if (matchingPlugin is not null) +
+ + @T("Configuration plugin ID:") @matchingPlugin.Id + +
+ @if (this.IsManagedConfigurationIdMismatch(matchingPlugin, env.ConfigurationId)) {
- - @T("Configuration plugin ID:") @matchingPlugin.Id - + + @T("ID mismatch: the plugin ID differs from the enterprise configuration ID.")
}
diff --git a/app/MindWork AI Studio/Pages/Information.razor.cs b/app/MindWork AI Studio/Pages/Information.razor.cs index a4eb5123..2027285f 100644 --- a/app/MindWork AI Studio/Pages/Information.razor.cs +++ b/app/MindWork AI Studio/Pages/Information.razor.cs @@ -69,13 +69,20 @@ public partial class Information : MSGComponentBase private bool showDatabaseDetails; - private List configPlugins = PluginFactory.AvailablePlugins.Where(x => x.Type is PluginType.CONFIGURATION).ToList(); + private List configPlugins = PluginFactory.AvailablePlugins + .Where(x => x.Type is PluginType.CONFIGURATION) + .OfType() + .ToList(); private sealed record DatabaseDisplayInfo(string Label, string Value); private readonly List databaseDisplayInfo = new(); private static bool HasAnyActiveEnvironment => EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.Any(e => e.IsActive); + + private bool HasAnyLoadedEnterpriseConfigurationPlugin => EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS + .Where(e => e.IsActive) + .Any(env => this.FindManagedConfigurationPlugin(env.ConfigurationId) is not null); /// /// Determines whether the enterprise configuration has details that can be shown/hidden. @@ -130,7 +137,10 @@ public partial class Information : MSGComponentBase switch (triggeredEvent) { case Event.PLUGINS_RELOADED: - this.configPlugins = PluginFactory.AvailablePlugins.Where(x => x.Type is PluginType.CONFIGURATION).ToList(); + this.configPlugins = PluginFactory.AvailablePlugins + .Where(x => x.Type is PluginType.CONFIGURATION) + .OfType() + .ToList(); await this.InvokeAsync(this.StateHasChanged); break; } @@ -196,6 +206,18 @@ public partial class Information : MSGComponentBase this.showDatabaseDetails = !this.showDatabaseDetails; } + private IAvailablePlugin? FindManagedConfigurationPlugin(Guid configurationId) + { + return this.configPlugins.FirstOrDefault(plugin => plugin.ManagedConfigurationId == configurationId) + // Backward compatibility for already downloaded plugins without ManagedConfigurationId. + ?? this.configPlugins.FirstOrDefault(plugin => plugin.ManagedConfigurationId is null && plugin.Id == configurationId); + } + + private bool IsManagedConfigurationIdMismatch(IAvailablePlugin plugin, Guid configurationId) + { + return plugin.ManagedConfigurationId == configurationId && plugin.Id != configurationId; + } + private async Task CopyStartupLogPath() { await this.RustService.CopyText2Clipboard(this.Snackbar, this.logPaths.LogStartupPath); diff --git a/app/MindWork AI Studio/Tools/PluginSystem/IAvailablePlugin.cs b/app/MindWork AI Studio/Tools/PluginSystem/IAvailablePlugin.cs index 540d2f08..d1221c0a 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/IAvailablePlugin.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/IAvailablePlugin.cs @@ -3,5 +3,8 @@ namespace AIStudio.Tools.PluginSystem; public interface IAvailablePlugin : IPluginMetadata { public string LocalPath { get; } + public bool IsManagedByConfigServer { get; } + + public Guid? ManagedConfigurationId { get; } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs index bc4c8671..9fa39bde 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs @@ -109,6 +109,7 @@ public static partial class PluginFactory pluginPath.StartsWith(CONFIGURATION_PLUGINS_ROOT, StringComparison.OrdinalIgnoreCase); var isManagedByConfigServer = false; + Guid? managedConfigurationId = null; if (plugin is PluginConfiguration configPlugin) { if (configPlugin.DeployedUsingConfigServer.HasValue) @@ -123,14 +124,20 @@ public static partial class PluginFactory // For configuration plugins, validate that the plugin ID matches the enterprise config ID // (the directory name under which the plugin was downloaded): - if (isConfigurationPluginInConfigDirectory) + if (isConfigurationPluginInConfigDirectory && isManagedByConfigServer) { var directoryName = Path.GetFileName(pluginPath); - if (Guid.TryParse(directoryName, out var enterpriseConfigId) && enterpriseConfigId != plugin.Id) - LOG.LogWarning($"The configuration plugin's ID ('{plugin.Id}') does not match the enterprise configuration ID ('{enterpriseConfigId}'). These IDs should be identical. Please update the plugin's ID field to match the enterprise configuration ID."); + if (Guid.TryParse(directoryName, out var enterpriseConfigId)) + { + managedConfigurationId = enterpriseConfigId; + if (enterpriseConfigId != plugin.Id) + LOG.LogWarning($"The configuration plugin's ID ('{plugin.Id}') does not match the enterprise configuration ID ('{enterpriseConfigId}'). These IDs should be identical. Please update the plugin's ID field to match the enterprise configuration ID."); + } + else + LOG.LogWarning($"Could not determine the managed configuration ID for configuration plugin '{plugin.Id}'. The plugin directory '{pluginPath}' does not end with a valid GUID."); } - AVAILABLE_PLUGINS.Add(new PluginMetadata(plugin, pluginPath, isManagedByConfigServer)); + AVAILABLE_PLUGINS.Add(new PluginMetadata(plugin, pluginPath, isManagedByConfigServer, managedConfigurationId)); } catch (Exception e) { diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginMetadata.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginMetadata.cs index 84889f55..db07035a 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/PluginMetadata.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginMetadata.cs @@ -1,6 +1,6 @@ namespace AIStudio.Tools.PluginSystem; -public sealed class PluginMetadata(PluginBase plugin, string localPath, bool isManagedByConfigServer = false) : IAvailablePlugin +public sealed class PluginMetadata(PluginBase plugin, string localPath, bool isManagedByConfigServer = false, Guid? managedConfigurationId = null) : IAvailablePlugin { #region Implementation of IPluginMetadata @@ -53,6 +53,8 @@ public sealed class PluginMetadata(PluginBase plugin, string localPath, bool isM public string LocalPath { get; } = localPath; public bool IsManagedByConfigServer { get; } = isManagedByConfigServer; + + public Guid? ManagedConfigurationId { get; } = managedConfigurationId; #endregion }