Пример #1
0
        public void ShouldReturnAllDependenciesIncludingFeatureForAGivenFeatureOrdered()
        {
            var features = ModuleScopedExtensionManager.GetFeatureDependencies("Sample3");

            Assert.Equal(3, features.Count());
            Assert.Equal("Sample1", features.ElementAt(0).Id);
            Assert.Equal("Sample2", features.ElementAt(1).Id);
            Assert.Equal("Sample3", features.ElementAt(2).Id);
        }
        private IEnumerable <IFeatureInfo> GetFeaturesToEnable(IFeatureInfo featureInfo)
        {
            var featuresToEnable = _extensionManager
                                   .GetFeatureDependencies(featureInfo.Id)
                                   .ToList();

            return(featuresToEnable);
        }
Пример #3
0
        public async Task <ActionResult> Integrations()
        {
            if (!await _authorizationService.AuthorizeAsync(User, OrchardCore.Features.Permissions.ManageFeatures)) // , T["Not allowed to manage features."]
            {
                return(Unauthorized());
            }

            var enabledFeatures = await _shellFeaturesManager.GetEnabledFeaturesAsync();

            // var alwaysEnabledFeatures = await _shellFeaturesManager.GetAlwaysEnabledFeaturesAsync();
//           var integrationFeatures = enabledFeatures.Where(extensionDescriptor =>
//           {
//               var tags = extensionDescriptor.Extension.Manifest.Tags.ToArray();
//               var isIntegrationFeature =
//                   tags.Any(x => string.Equals(x, "integration", StringComparison.OrdinalIgnoreCase));
//
//               return isIntegrationFeature;
//           });

            var moduleFeatures = new List <ModuleFeature>();

            foreach (var moduleFeatureInfo in _extensionManager
                     .GetFeatures()
                     .Where(f => !f.Extension.IsTheme() && FeatureIsAllowed(f)))
            {
                var dependentFeatures    = _extensionManager.GetDependentFeatures(moduleFeatureInfo.Id);
                var featureDependencies  = _extensionManager.GetFeatureDependencies(moduleFeatureInfo.Id);
                var isIntegrationFeature = IsIntegrationFeature(moduleFeatureInfo.Extension.Manifest);

                if (isIntegrationFeature == true)
                {
                    var moduleFeature = new ModuleFeature
                    {
                        Descriptor = moduleFeatureInfo,
                        IsEnabled  = enabledFeatures.Contains(moduleFeatureInfo),
                        // IsAlwaysEnabled = alwaysEnabledFeatures.Contains(moduleFeatureInfo),
                        //IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(f.Extension),
                        //NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id),
                        EnabledDependentFeatures = dependentFeatures.Where(x => x.Id != moduleFeatureInfo.Id).ToList(),
                        FeatureDependencies      = featureDependencies.Where(d => d.Id != moduleFeatureInfo.Id).ToList()
                    };

                    moduleFeatures.Add(moduleFeature);
                }
            }

            return(View(new FeaturesViewModel
            {
                Features = moduleFeatures,
                IsAllowed = FeatureIsAllowed
            }));
        }
        /// <summary>
        /// Enables a feature.
        /// </summary>
        /// <param name="featureInfo">The info of the feature to be enabled.</param>
        /// <param name="enabledFeatureIds">The list of feature ids which are currently enabled.</param>
        /// <param name="force">Boolean parameter indicating if the feature should enable it's dependencies.</param>
        /// <returns>An enumeration of the features to disable, empty if 'force' = true and a dependency is disabled</returns>
        private IEnumerable <IFeatureInfo> GetFeaturesToEnable(IFeatureInfo featureInfo, IEnumerable <string> enabledFeatureIds, bool force)
        {
            var featuresToEnable = _extensionManager
                                   .GetFeatureDependencies(featureInfo.Id)
                                   .Where(f => !enabledFeatureIds.Contains(f.Id))
                                   .ToList();

            if (featuresToEnable.Count > 1 && !force)
            {
                if (_logger.IsEnabled(LogLevel.Warning))
                {
                    _logger.LogWarning(" To enable '{FeatureId}', additional features need to be enabled.", featureInfo.Id);
                }

                return(Enumerable.Empty <IFeatureInfo>());
            }

            return(featuresToEnable);
        }
Пример #5
0
        public async Task <ShellBlueprint> ComposeAsync(ShellSettings settings, ShellDescriptor descriptor)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Composing blueprint");
            }

            var enabledFeatures = descriptor
                                  .Features
                                  .SelectMany(shellFeature => _extensionManager.GetFeatureDependencies(shellFeature.Id))
                                  .Distinct()
                                  .ToArray();

            var features = await Task.WhenAll(enabledFeatures.Select(ef => _extensionManager.LoadFeatureAsync(ef)));

            // Statup classes are the only types that are automatically added to the blueprint
            var dependencies = BuildBlueprint(features, IsStartup, BuildModule, Enumerable.Empty <string>());

            var uniqueDependencies = new Dictionary <Type, DependencyBlueprint>();

            foreach (var dependency in dependencies)
            {
                if (!uniqueDependencies.ContainsKey(dependency.Type))
                {
                    uniqueDependencies.Add(dependency.Type, dependency);
                }
            }

            var result = new ShellBlueprint
            {
                Settings     = settings,
                Descriptor   = descriptor,
                Dependencies = uniqueDependencies.Values
            };

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Done composing blueprint");
            }
            return(result);
        }
Пример #6
0
        public async Task <ActionResult> Features()
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageFeatures))
            {
                return(Forbid());
            }

            var enabledFeatures = await _shellFeaturesManager.GetEnabledFeaturesAsync();

            var alwaysEnabledFeatures = await _shellFeaturesManager.GetAlwaysEnabledFeaturesAsync();

            var moduleFeatures = new List <ModuleFeature>();

            foreach (var moduleFeatureInfo in _extensionManager
                     .GetFeatures()
                     .Where(f => !f.Extension.IsTheme() && FeatureIsAllowed(f)))
            {
                var dependentFeatures   = _extensionManager.GetDependentFeatures(moduleFeatureInfo.Id);
                var featureDependencies = _extensionManager.GetFeatureDependencies(moduleFeatureInfo.Id);

                var moduleFeature = new ModuleFeature
                {
                    Descriptor      = moduleFeatureInfo,
                    IsEnabled       = enabledFeatures.Contains(moduleFeatureInfo),
                    IsAlwaysEnabled = alwaysEnabledFeatures.Contains(moduleFeatureInfo),
                    //IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(f.Extension),
                    //NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id),
                    DependentFeatures   = dependentFeatures.Where(x => x.Id != moduleFeatureInfo.Id).ToList(),
                    FeatureDependencies = featureDependencies.Where(d => d.Id != moduleFeatureInfo.Id).ToList()
                };

                moduleFeatures.Add(moduleFeature);
            }

            return(View(new FeaturesViewModel
            {
                Features = moduleFeatures,
                IsAllowed = FeatureIsAllowed
            }));
        }
Пример #7
0
        /// <summary>
        /// Enables a feature.
        /// </summary>
        /// <param name="featureId">The ID of the feature to be enabled.</param>
        /// <param name="availableFeatures">A dictionary of the available feature descriptors and their current state (enabled / disabled).</param>
        /// <param name="force">Boolean parameter indicating if the feature should enable it's dependencies if required or fail otherwise.</param>
        /// <returns>An enumeration of the enabled features.</returns>
        private IEnumerable <IFeatureInfo> GetFeaturesToEnable(
            IFeatureInfo featureInfo,
            bool force)
        {
            var featuresToEnable = _extensionManager
                                   .GetFeatureDependencies(featureInfo.Id)
                                   .ToList();

            if (featuresToEnable.Count > 1 && !force)
            {
                if (_logger.IsEnabled(LogLevel.Warning))
                {
                    _logger.LogWarning("Additional features need to be enabled.");
                }
                if (FeatureDependencyNotification != null)
                {
                    FeatureDependencyNotification("If {0} is enabled, then you'll also need to enable {1}.", featureInfo, featuresToEnable.Where(f => f.Id != featureInfo.Id));
                }
            }

            return(featuresToEnable);
        }
Пример #8
0
 private bool IsBaseTheme(string themeFeatureId, string themeId)
 {
     return(_extensionManager
            .GetFeatureDependencies(themeId)
            .Any(f => f.Id == themeFeatureId));
 }
Пример #9
0
        public async Task UpdateAsync(string featureId)
        {
            if (_processedFeatures.Contains(featureId))
            {
                return;
            }

            _processedFeatures.Add(featureId);

            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation("Updating feature '{FeatureName}'", featureId);
            }

            // proceed with dependent features first, whatever the module it's in
            var dependencies = _extensionManager
                               .GetFeatureDependencies(
                featureId)
                               .Where(x => x.Id != featureId)
                               .Select(x => x.Id);

            await UpdateAsync(dependencies);

            var migrations = GetDataMigrations(featureId);

            // apply update methods to each migration class for the module
            foreach (var migration in migrations)
            {
                var schemaBuilder = new SchemaBuilder(_store.Configuration, await _session.DemandAsync());
                migration.SchemaBuilder = schemaBuilder;

                // copy the object for the Linq query
                var tempMigration = migration;

                // get current version for this migration
                var dataMigrationRecord = await GetDataMigrationRecordAsync(tempMigration);

                var current = 0;
                if (dataMigrationRecord != null)
                {
                    // This can be null if a failed create migration has occured and the data migration record was saved.
                    current = dataMigrationRecord.Version.HasValue ? dataMigrationRecord.Version.Value : current;
                }
                else
                {
                    dataMigrationRecord = new Records.DataMigration {
                        DataMigrationClass = migration.GetType().FullName
                    };
                    _dataMigrationRecord.DataMigrations.Add(dataMigrationRecord);
                }

                try
                {
                    // do we need to call Create() ?
                    if (current == 0)
                    {
                        // try to resolve a Create method

                        var createMethod = GetCreateMethod(migration);
                        if (createMethod != null)
                        {
                            current = (int)createMethod.Invoke(migration, new object[0]);
                        }

                        // try to resolve a CreateAsync method

                        var createAsyncMethod = GetCreateAsyncMethod(migration);
                        if (createAsyncMethod != null)
                        {
                            current = await(Task <int>) createAsyncMethod.Invoke(migration, new object[0]);
                        }
                    }

                    var lookupTable = CreateUpgradeLookupTable(migration);

                    while (lookupTable.TryGetValue(current, out var methodInfo))
                    {
                        if (_logger.IsEnabled(LogLevel.Information))
                        {
                            _logger.LogInformation("Applying migration for '{FeatureName}' from version {Version}.", featureId, current);
                        }

                        var isAwaitable = methodInfo.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null;
                        if (isAwaitable)
                        {
                            current = await(Task <int>) methodInfo.Invoke(migration, new object[0]);
                        }
                        else
                        {
                            current = (int)methodInfo.Invoke(migration, new object[0]);
                        }
                    }

                    // if current is 0, it means no upgrade/create method was found or succeeded
                    if (current == 0)
                    {
                        return;
                    }

                    dataMigrationRecord.Version = current;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error while running migration version {Version} for '{FeatureName}'.", current, featureId);

                    _session.Cancel();
                }
                finally
                {
                    // Persist data migrations
                    _session.Save(_dataMigrationRecord);
                }
            }
        }
Пример #10
0
 public static IEnumerable <IFeatureInfo> GetEnabledFeatures(this IExtensionManager extensionManager, ShellDescriptor shellDescriptor)
 {
     return(shellDescriptor.Features.SelectMany(shellFeature => extensionManager.GetFeatureDependencies(shellFeature.Id)).Distinct());
 }