Esempio n. 1
0
        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));
        }
Esempio n. 9
0
        /// <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!");
            }
        }
Esempio n. 10
0
 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;
 }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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;
                }
            }
        }
Esempio n. 13
0
        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();
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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
            });
        }
Esempio n. 17
0
 public Task <IEnumerable <IFeatureInfo> > DisableFeaturesAsync(EngineDescriptor engineDescriptor, IEnumerable <IFeatureInfo> features)
 {
     return(DisableFeaturesAsync(engineDescriptor, features, false));
 }
Esempio n. 18
0
        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);
        }