public async Task <IEnumerable <IFeatureInfo> > EnableFeaturesAsync(EngineDescriptor engineDescriptor, IEnumerable <IFeatureInfo> features, bool force) { var featuresToEnable = features .SelectMany(feature => GetFeaturesToEnable(feature, force)) .Distinct() .ToList(); if (featuresToEnable.Count > 0) { if (_logger.IsEnabled(LogLevel.Information)) { foreach (var feature in featuresToEnable) { _logger.LogInformation("Enabling feature '{FeatureName}'", feature.Id); } } var enabledFeatures = await _pluginManager .LoadFeaturesAsync(engineDescriptor.Features.Select(x => x.Id).ToArray()); engineDescriptor.Features = enabledFeatures .Select(x => x.FeatureInfo) .Concat(featuresToEnable) .Distinct() .Select(x => new EngineFeature(x.Id)) .ToList(); await _engineDescriptorManager.UpdateEngineDescriptorAsync( engineDescriptor.SerialNumber, engineDescriptor.Features, engineDescriptor.Parameters); } return(featuresToEnable); }
private void FireApplyChangesIfNeeded() { _deferredTaskEngine.AddTask(async context => { var stateManager = context.ServiceProvider.GetRequiredService <IEngineStateManager>(); var engineStateUpdater = context.ServiceProvider.GetRequiredService <IEngineStateUpdater>(); var engineState = await stateManager.GetEngineStateAsync(); while (engineState.Features.Any(FeatureIsChanging)) { var descriptor = new EngineDescriptor { Features = engineState.Features .Where(FeatureShouldBeLoadedForStateChangeNotifications) .Select(x => new EngineFeature { Id = x.Id }) .ToArray() }; if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Adding pending task 'ApplyChanges' for tenant '{TenantName}'", _settings.Name); } await engineStateUpdater.ApplyChanges(); } }); }
public EngineFeaturesManager( IPluginManager pluginManager, EngineDescriptor engineDescriptor, IEngineDescriptorFeaturesManager engineDescriptorFeaturesManager) { _pluginManager = pluginManager; _engineDescriptor = engineDescriptor; _engineDescriptorFeaturesManager = engineDescriptorFeaturesManager; }
public Task <EngineDescriptor> GetEngineDescriptorAsync() { if (_engineDescriptor == null) { _engineDescriptor = new EngineDescriptor { Features = _engineFeatures.Distinct().ToList() }; } return(Task.FromResult(_engineDescriptor)); }
public async Task UpdateEngineDescriptorAsync(int priorSerialNumber, IEnumerable <EngineFeature> enabledFeatures, IEnumerable <EngineParameter> parameters) { var engineDescriptorRecord = await GetEngineDescriptorAsync(); var serialNumber = engineDescriptorRecord == null ? 0 : engineDescriptorRecord.SerialNumber; if (priorSerialNumber != serialNumber) { throw new InvalidOperationException("运行环境序列号错误"); } if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Updating engine descriptor for tenant '{TenantName}' ...", _engineSettings.Name); } bool newRecord = engineDescriptorRecord == null; if (newRecord) { engineDescriptorRecord = new EngineDescriptor { SerialNumber = 1 }; } else { engineDescriptorRecord.SerialNumber++; } engineDescriptorRecord.Features = enabledFeatures.ToList(); engineDescriptorRecord.Parameters = parameters.ToList(); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Engine descriptor updated for tenant '{TenantName}'.", _engineSettings.Name); } if (newRecord) { _engineDescriptorSet.Add(engineDescriptorRecord); } else { _engineDescriptorSet.Update(engineDescriptorRecord); } _db.SaveChanges(); _engineDescriptor = engineDescriptorRecord; await _engineDescriptorManagerEventHandlers.InvokeAsync(e => e.Changed(engineDescriptorRecord, _engineSettings.Name), _logger); }
public Task <EngineDescriptor> GetEngineDescriptorAsync() { if (_engineDescriptor == null) { _engineDescriptor = new EngineDescriptor { Features = _pluginManager.GetFeatures().Select(x => new EngineFeature { Id = x.Id }).ToList() }; } return(Task.FromResult(_engineDescriptor)); }
public async Task <EngineDescriptor> GetEngineDescriptorAsync() { if (_engineDescriptor == null) { _engineDescriptor = await Task.FromResult(_engineDescriptorSet.FirstOrDefault()); if (_engineDescriptor != null) { _engineDescriptor.Features = _alwaysEnabledFeatures.Concat( _engineDescriptor.Features).Distinct().ToList(); } } return(_engineDescriptor); }
public Task <EngineDescriptor> GetEngineDescriptorAsync() { if (_engineDescriptor == null) { var features = _alwaysEnabledFeatures.Concat(_engineSettings.Features .Select(id => new EngineFeature(id))).Distinct().ToList(); _engineDescriptor = new EngineDescriptor { Features = features }; } return(Task.FromResult(_engineDescriptor)); }
/// <summary> /// Reads information about supported table engines /// </summary> private void ReadTableEngines() { // Read schema aditional information DataTable table = EngineDescriptor.Enumerate(this, null); // Exctract default character set and collation names if (table != null && table.Columns.Contains(EngineDescriptor.Attributes.Name) && table.Columns.Contains(EngineDescriptor.Attributes.IsSupported)) { FillTableEngines(table); } else { Debug.Fail("Unable to read table engines!"); } }
public DataMigrationManager( IStore store, IDataMigrator dataMigrator, IPluginManager pluginManager, IEngineStateManager engineStateManager, EngineSettings engineSettings, EngineDescriptor engineDescriptor, IServiceProvider serviceProvider, ILogger <DataMigrationManager> logger) { _store = store; _dataMigrator = dataMigrator; _pluginManager = pluginManager; _engineStateManager = engineStateManager; _engineSettings = engineSettings; _engineDescriptor = engineDescriptor; _serviceProvider = serviceProvider; _logger = logger; }
Task IEngineDescriptorManagerEventHandler.Changed(EngineDescriptor descriptor, string tenant) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("A tenant needs to be restarted '{TenantName}'", tenant); } if (_engineContexts == null) { return(Task.CompletedTask); } if (_engineContexts.TryRemove(tenant, out var context)) { context.Release(); } return(Task.CompletedTask); }
public ModuleViewLocationExpanderProvider( IRazorViewEngineFileProviderAccessor fileProviderAccessor, IPluginManager pluginManager, EngineDescriptor engineDescriptor, IMemoryCache memoryCache) { _pluginManager = pluginManager; _engineDescriptor = engineDescriptor; _memoryCache = memoryCache; if (_modulesWithComponentViews != null) { return; } lock (_synLock) { if (_modulesWithComponentViews == null) { var modulesWithComponentViews = new List <IPluginInfo>(); var orderedModules = _pluginManager.GetPlugins() //.Where(e => e.Manifest.Type.Equals("module", StringComparison.OrdinalIgnoreCase)) .Reverse(); foreach (var module in orderedModules) { var moduleComponentsViewFilePaths = fileProviderAccessor.FileProvider.GetViewFilePaths( module.SubPath + "/Views/Shared/Components", new[] { RazorViewEngine.ViewExtension }, viewsFolder: null, inViewsFolder: true, inDepth: true); if (moduleComponentsViewFilePaths.Any()) { modulesWithComponentViews.Add(module); } } _modulesWithComponentViews = modulesWithComponentViews; } } }
public async Task <EngineSchema> ComposeAsync(EngineSettings settings, EngineDescriptor descriptor) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Composing schema"); } var featureNames = descriptor.Features.Select(x => x.Id).ToArray(); var features = await _pluginManager.LoadFeaturesAsync(featureNames); var entries = new Dictionary <Type, FeatureEntry>(); foreach (var feature in features) { foreach (var exportedType in feature.ExportedTypes) { var requiredFeatures = RequireFeaturesAttribute.GetRequiredFeatureNamesForType(exportedType); if (requiredFeatures.All(x => featureNames.Contains(x))) { entries.Add(exportedType, feature); } } } var result = new EngineSchema { Settings = settings, Descriptor = descriptor, Dependencies = entries }; if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Done composing schema"); } return(result); }
async Task IEngineDescriptorManagerEventHandler.Changed(EngineDescriptor descriptor, string tenant) { var engineState = await _stateManager.GetEngineStateAsync(); foreach (var feature in descriptor.Features) { var featureId = feature.Id; var featureState = engineState.Features.SingleOrDefault(f => f.Id == featureId); if (featureState == null) { featureState = new EngineFeatureState { Id = featureId }; } if (!featureState.IsInstalled) { await _stateManager.UpdateInstalledStateAsync(featureState, EngineFeatureState.States.Rising); } if (!featureState.IsEnabled) { await _stateManager.UpdateEnabledStateAsync(featureState, EngineFeatureState.States.Rising); } } foreach (var featureState in engineState.Features) { var featureId = featureState.Id; if (descriptor.Features.Any(f => f.Id == featureId)) { continue; } if (!featureState.IsDisabled) { await _stateManager.UpdateEnabledStateAsync(featureState, EngineFeatureState.States.Falling); } } FireApplyChangesIfNeeded(); }
public async Task <IEnumerable <IFeatureInfo> > DisableFeaturesAsync(EngineDescriptor engineDescriptor, IEnumerable <IFeatureInfo> features, bool force) { var alwaysEnabledIds = _alwaysEnabledFeatures.Select(sf => sf.Id).ToArray(); var featuresToDisable = features .Where(f => !alwaysEnabledIds.Contains(f.Id)) .SelectMany(feature => GetFeaturesToDisable(feature, force)) .Distinct() .ToList(); if (featuresToDisable.Count > 0) { var loadedFeatures = await _pluginManager.LoadFeaturesAsync(engineDescriptor.Features.Select(x => x.Id).ToArray()); var enabledFeatures = loadedFeatures.Select(x => x.FeatureInfo).ToList(); foreach (var feature in featuresToDisable) { enabledFeatures.Remove(feature); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Feature '{FeatureName}' was disabled", feature.Id); } } engineDescriptor.Features = enabledFeatures.Select(x => new EngineFeature(x.Id)).ToList(); await _engineDescriptorManager.UpdateEngineDescriptorAsync( engineDescriptor.SerialNumber, engineDescriptor.Features, engineDescriptor.Parameters); } return(featuresToDisable); }
public async Task <EngineContext> CreateDescribedContextAsync(EngineSettings settings, EngineDescriptor engineDescriptor) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Creating described context for tenant '{TenantName}'", settings.Name); } var schema = await _compositionStrategy.ComposeAsync(settings, engineDescriptor); var provider = _engineContainerFactory.CreateContainer(settings, schema); return(new EngineContext { Settings = settings, Schema = schema, ServiceProvider = provider }); }
public Task <IEnumerable <IFeatureInfo> > DisableFeaturesAsync(EngineDescriptor engineDescriptor, IEnumerable <IFeatureInfo> features) { return(DisableFeaturesAsync(engineDescriptor, features, false)); }
private async Task <string> ExecuteSetupAsync(SetupContext context) { var defaultEnables = new string[] { //"SeedModules.Project" //"SeedModules.Security"// 先把Security引入,不然执行模块安装后事件时需要写权限数据时找不到表 }; context.EnabledFeatures = defaultEnables.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList(); _engineSettings.State = TenantStates.Initializing; var engineSettings = new EngineSettings(_engineSettings.Configuration); if (string.IsNullOrEmpty(engineSettings.DatabaseProvider)) { engineSettings.ConnectionString = context.DatabaseConnectionString; engineSettings.DatabaseProvider = context.DatabaseProvider; engineSettings.TablePrefix = context.DatabaseTablePrefix; } var engineDescriptor = new EngineDescriptor() { Features = context.EnabledFeatures.Select(e => new EngineFeature(e)).ToList() }; var executionId = string.Empty; using (var engineContext = await _engineContextFactory.CreateDescribedContextAsync(engineSettings, engineDescriptor)) { using (var scope = engineContext.EnterServiceScope()) { // 初始化数据库 try { var store = scope.ServiceProvider.GetRequiredService <IStore>(); await store.InitializeAsync(scope.ServiceProvider); } catch (Exception e) { context.Errors.Add("DatabaseProvider", string.Format("初始化数据库访问时发生异常: {0}", e.Message)); return(null); } // 刷新 EngineDescriptor await scope.ServiceProvider .GetService <IEngineDescriptorManager>() .UpdateEngineDescriptorAsync(0, engineContext.Schema.Descriptor.Features, engineContext.Schema.Descriptor.Parameters); // 后台延迟进程服务 var deferredTaskEngine = scope.ServiceProvider.GetService <IDeferredTaskEngine>(); if (deferredTaskEngine != null && deferredTaskEngine.HasPendingTasks) { await deferredTaskEngine.ExecuteTasksAsync(new DeferredTaskContext(scope.ServiceProvider)); } } // 用于前台检测执行状态和状态执行回溯 executionId = Guid.NewGuid().ToString("n"); using (var scope = engineContext.EnterServiceScope()) { await scope.ServiceProvider.GetService <IProjectExecutor>() .ExecuteAsync(executionId, context.Project, new { context.Name, context.AdminUsername, context.AdminEmail, context.AdminPassword, context.DatabaseProvider, context.DatabaseConnectionString, context.DatabaseTablePrefix }); } } // 安装事件 using (var engineContext = await _engineHost.CreateEngineContextAsync(engineSettings)) { using (var scope = engineContext.EnterServiceScope()) { var hasErrors = false; await scope.ServiceProvider.GetServices <ISetupEventHandler>().InvokeAsync(x => x.SetupAsync( context.Name, context.AdminUsername, context.AdminEmail, context.AdminPassword, context.DatabaseProvider, context.DatabaseConnectionString, context.DatabaseTablePrefix, (key, message) => { hasErrors = true; context.Errors[key] = message; } ), scope.ServiceProvider.GetRequiredService <ILogger <SetupService> >()); if (hasErrors) { return(executionId); } } } engineSettings.State = TenantStates.Running; _engineHost.UpdateEngineSettings(engineSettings); return(executionId); }