Ejemplo n.º 1
0
        ShellContext IShellContextFactory.CreateShellContext(
            ShellSettings settings)
        {
            var sw = Stopwatch.StartNew();

            _logger.LogInformation("Creating shell context for tenant {0}", settings.Name);

            var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor());
            var provider  = _shellContainerFactory.CreateContainer(settings, blueprint);

            try {
                var shellcontext = new ShellContext {
                    Settings      = settings,
                    Blueprint     = blueprint,
                    LifetimeScope = provider,
                    Shell         = provider.GetRequiredService <IOrchardShell>()
                };

                _logger.LogVerbose("Created shell context for tenant {0} in {1}ms", settings.Name, sw.ElapsedMilliseconds);

                return(shellcontext);
            }
            catch (Exception ex) {
                _logger.LogError("Cannot create shell context", ex);
                throw;
            }
        }
Ejemplo n.º 2
0
        ShellContext IShellContextFactory.CreateShellContext(ShellSettings settings)
        {
            var sw = Stopwatch.StartNew();

            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation("Creating shell context for tenant {0}", settings.Name);
            }
            var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor());
            var provider  = _shellContainerFactory.CreateContainer(settings, blueprint);

            try
            {
                var shellcontext = new ShellContext
                {
                    Settings        = settings,
                    Blueprint       = blueprint,
                    ServiceProvider = provider
                };

                if (_logger.IsEnabled(LogLevel.Verbose))
                {
                    _logger.LogVerbose("Created shell context for tenant {0} in {1}ms", settings.Name, sw.ElapsedMilliseconds);
                }
                return(shellcontext);
            }
            catch (Exception ex)
            {
                _logger.LogError("Cannot create shell context", ex);
                throw;
            }
        }
        /// <summary>
        /// 创建一个外壳上下文工厂。
        /// </summary>
        /// <param name="settings">外壳设置。</param>
        /// <returns>外壳上下文。</returns>
        public ShellContext CreateShellContext(ShellSettings settings)
        {
            Logger.Debug("准备为租户 {0} 创建外壳上下文", settings.Name);

            var knownDescriptor = _shellDescriptorCache.Fetch(settings.Name);

            if (knownDescriptor == null)
            {
                Logger.Information("在缓存中找不到外壳描述符信息。 以最少的组件开始。");
                var features = new List <ShellFeature>();
                _minimumShellDescriptorProviders.Invoke(i => i.GetFeatures(features), Logger);
                knownDescriptor = MinimumShellDescriptor(features);
            }

            var blueprint  = _compositionStrategy.Compose(settings, knownDescriptor);
            var shellScope = _shellContainerFactory.CreateContainer(settings, blueprint);

            ShellDescriptor currentDescriptor;

            using (var standaloneEnvironment = shellScope.CreateWorkContextScope())
            {
                var shellDescriptorManager = standaloneEnvironment.Resolve <IShellDescriptorManager>();
                currentDescriptor = shellDescriptorManager.GetShellDescriptor();
            }

            if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber)
            {
                currentDescriptor.Features = currentDescriptor.Features.Distinct(new ShellFeatureEqualityComparer()).ToArray();
                Logger.Information("获得较新的外壳描述符。重新构建外壳容器。");

                _shellDescriptorCache.Store(settings.Name, currentDescriptor);
                blueprint = _compositionStrategy.Compose(settings, currentDescriptor);
                shellScope.Dispose();
                shellScope = _shellContainerFactory.CreateContainer(settings, blueprint);
            }

            return(new ShellContext
            {
                Settings = settings,
                Descriptor = currentDescriptor,
                Blueprint = blueprint,
                Container = shellScope,
                Shell = shellScope.Resolve <IShell>(),
            });
        }
        private void ExecuteOnTenantScope(ShellSettings settings, Action <IWorkContextScope> action)
        {
            var shellContext = _shellContextFactory.CreateShellContext(settings);

            using (var container = _shellContainerFactory.CreateContainer(shellContext.Settings, shellContext.Blueprint)) {
                using (var environment = container.CreateWorkContextScope()) {
                    action(environment);
                }
            }
        }
        public ShellContext CreateShellContext(ShellSettings settings)
        {
            Logger.Debug("Creating shell context for tenant {0}", settings.Name);

            var knownDescriptor = _shellDescriptorCache.Fetch(settings.Name);

            if (knownDescriptor == null)
            {
                Logger.Information("No descriptor cached. Starting with minimum components.");
                knownDescriptor = MinimumShellDescriptor();
            }

            var blueprint  = _compositionStrategy.Compose(settings, knownDescriptor);
            var shellScope = _shellContainerFactory.CreateContainer(settings, blueprint);

            ShellDescriptor currentDescriptor;

            using (var standaloneEnvironment = shellScope.CreateWorkContextScope())
            {
                var shellDescriptorManager = standaloneEnvironment.Resolve <IShellDescriptorManager>();
                currentDescriptor = shellDescriptorManager.GetShellDescriptor();
            }

            if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber)
            {
                Logger.Information("Newer descriptor obtained. Rebuilding shell container.");

                _shellDescriptorCache.Store(settings.Name, currentDescriptor);
                blueprint = _compositionStrategy.Compose(settings, currentDescriptor);
                shellScope.Dispose();
                shellScope = _shellContainerFactory.CreateContainer(settings, blueprint);
            }

            return(new ShellContext
            {
                Settings = settings,
                Descriptor = currentDescriptor,
                Blueprint = blueprint,
                LifetimeScope = shellScope,
                Shell = shellScope.Resolve <IBoyingShell>(),
            });
        }
Ejemplo n.º 6
0
        ShellContext IShellContextFactory.CreateShellContext(
            ShellSettings settings)
        {
            _logger.LogInformation("Creating shell context for tenant {0}", settings.Name);

            var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor());
            var provider  = _shellContainerFactory.CreateContainer(settings, blueprint);

            try {
                return(new ShellContext {
                    Settings = settings,
                    Blueprint = blueprint,
                    LifetimeScope = provider,
                    Shell = provider.GetRequiredService <IOrchardShell>()
                });
            }
            catch (Exception ex) {
                _logger.LogError("Cannot create shell context", ex);
                throw;
            }
        }
Ejemplo n.º 7
0
        public ShellContext CreateDescribedContext(IShellSettings settings, IShellDescriptor descriptor)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Creating described context for tenant {0}", settings.Name);
            }

            var blueprint       = _compositionStrategy.ComposeAsync(settings, descriptor).Result;
            var serviceProvider = _shellContainerFactory.CreateContainer(settings, blueprint);

            return(new ShellContext
            {
                Settings = settings,
                Blueprint = blueprint,
                ServiceProvider = serviceProvider
            });
        }
Ejemplo n.º 8
0
        public async Task <ShellContext> CreateDescribedContextAsync(ShellSettings settings, ShellDescriptor shellDescriptor)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Creating described context for tenant '{TenantName}'", settings.Name);
            }

            var blueprint = await _compositionStrategy.ComposeAsync(settings, shellDescriptor);

            var provider = _shellContainerFactory.CreateContainer(settings, blueprint);

            return(new ShellContext
            {
                Settings = settings,
                Blueprint = blueprint,
                ServiceProvider = provider
            });
        }
Ejemplo n.º 9
0
        ShellContext IShellContextFactory.CreateShellContext(
            ShellSettings settings)
        {
            Console.WriteLine("Creating shell context for tenant {0}", settings.Name);

            var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor());
            var provider  = _shellContainerFactory.CreateContainer(settings, blueprint);

            try {
                return(new ShellContext {
                    Settings = settings,
                    Blueprint = blueprint,
                    LifetimeScope = provider,
                    Shell = provider.GetService <IOrchardShell>()
                });
            }
            catch (Exception ex) {
                Logger.Error(ex.ToString());
                throw;
            }
        }
Ejemplo n.º 10
0
        public string Setup(SetupContext context)
        {
            string executionId;

            Logger.Information("Running setup for tenant '{0}'.", _shellSettings.Name);

            // The vanilla Orchard distibution has the following features enabled.
            string[] hardcoded =
            {
                // Framework
                "Orchard.Framework",
                // Core
                "Common",           "Containers",             "Contents",       "Dashboard",     "Feeds",         "Navigation",      "Scheduling", "Settings", "Shapes", "Title",
                // Modules
                "Orchard.Pages",    "Orchard.ContentPicker",  "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules",
                "PackagingServices","Orchard.Packaging",      "Gallery",        "Orchard.Recipes"
            };

            context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList();

            var shellSettings = new ShellSettings(_shellSettings);

            if (String.IsNullOrEmpty(shellSettings.DataProvider))
            {
                shellSettings.DataProvider         = context.DatabaseProvider;
                shellSettings.DataConnectionString = context.DatabaseConnectionString;
                shellSettings.DataTablePrefix      = context.DatabaseTablePrefix;
            }

            shellSettings.EncryptionAlgorithm = "AES";
            shellSettings.EncryptionKey       = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString();
            shellSettings.HashAlgorithm       = "HMACSHA256";
            shellSettings.HashKey             = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString();

            var shellDescriptor = new ShellDescriptor {
                Features = context.EnabledFeatures.Select(name => new ShellFeature {
                    Name = name
                })
            };

            var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor);

            // Initialize database explicitly, and store shell descriptor.
            using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) {
                using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) {
                    // Workaround to avoid a Transaction issue with PostgreSQL.
                    environment.Resolve <ITransactionManager>().RequireNew();

                    var schemaBuilder = new SchemaBuilder(environment.Resolve <IDataMigrationInterpreter>());

                    schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table
                                              .Column <int>("Id", column => column.PrimaryKey().Identity())
                                              .Column <string>("DataMigrationClass")
                                              .Column <int>("Version"));

                    schemaBuilder.AlterTable("Orchard_Framework_DataMigrationRecord",
                                             table => table.AddUniqueConstraint("UC_DMR_DataMigrationClass_Version", "DataMigrationClass", "Version"));

                    var dataMigrationManager = environment.Resolve <IDataMigrationManager>();
                    dataMigrationManager.Update("Settings");

                    foreach (var feature in context.EnabledFeatures)
                    {
                        dataMigrationManager.Update(feature);
                    }

                    var descriptorManager = environment.Resolve <IShellDescriptorManager>();
                    descriptorManager.UpdateShellDescriptor(0, shellDescriptor.Features, shellDescriptor.Parameters);
                }
            }

            // In effect "pump messages" see PostMessage circa 1980.
            while (_processingEngine.AreTasksPending())
            {
                _processingEngine.ExecuteNextTask();
            }

            // Create a standalone environment.
            // Must mark state as Running - otherwise standalone environment is created "for setup".
            shellSettings.State = TenantState.Running;
            using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) {
                try {
                    executionId = CreateTenantData(context, environment);
                }
                catch {
                    environment.Resolve <ITransactionManager>().Cancel();
                    throw;
                }
            }

            _shellSettingsManager.SaveSettings(shellSettings);

            return(executionId);
        }
Ejemplo n.º 11
0
        public string Setup(SetupContext context)
        {
            string executionId;

            // The vanilla Orchard distibution has the following features enabled.
            string[] hardcoded =
            {
                // Framework
                "Orchard.Framework",
                // Core
                "Common",           "Containers",             "Contents",       "Dashboard",     "Feeds",         "Navigation",      "Reports", "Scheduling", "Settings", "Shapes", "Title",
                // Modules
                "Orchard.Pages",    "Orchard.ContentPicker",  "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules",
                "PackagingServices","Orchard.Packaging",      "Gallery",        "Orchard.Recipes"
            };

            context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList();

            var shellSettings = new ShellSettings(_shellSettings);

            if (string.IsNullOrEmpty(shellSettings.DataProvider))
            {
                shellSettings.DataProvider         = context.DatabaseProvider;
                shellSettings.DataConnectionString = context.DatabaseConnectionString;
                shellSettings.DataTablePrefix      = context.DatabaseTablePrefix;
            }

            #region Encryption Settings

            shellSettings.EncryptionAlgorithm = "AES";
            // randomly generated key
            shellSettings.EncryptionKey = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString();

            shellSettings.HashAlgorithm = "HMACSHA256";
            // randomly generated key
            shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString();

            #endregion

            var shellDescriptor = new ShellDescriptor {
                Features = context.EnabledFeatures.Select(name => new ShellFeature {
                    Name = name
                })
            };

            var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor);

            // initialize database explicitly, and store shell descriptor
            using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) {
                using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) {
                    // check if the database is already created (in case an exception occured in the second phase)
                    var schemaBuilder = new SchemaBuilder(environment.Resolve <IDataMigrationInterpreter>());
                    try {
                        var tablePrefix = String.IsNullOrEmpty(shellSettings.DataTablePrefix) ? "" : shellSettings.DataTablePrefix + "_";
                        schemaBuilder.ExecuteSql("SELECT * FROM " + tablePrefix + "Settings_ShellDescriptorRecord");
                    }
                    catch {
                        var reportsCoordinator = environment.Resolve <IReportsCoordinator>();

                        reportsCoordinator.Register("Data Migration", "Setup", "Orchard installation");

                        schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord",
                                                  table => table
                                                  .Column <int>("Id", column => column.PrimaryKey().Identity())
                                                  .Column <string>("DataMigrationClass")
                                                  .Column <int>("Version"));

                        var dataMigrationManager = environment.Resolve <IDataMigrationManager>();
                        dataMigrationManager.Update("Settings");

                        foreach (var feature in context.EnabledFeatures)
                        {
                            dataMigrationManager.Update(feature);
                        }

                        environment.Resolve <IShellDescriptorManager>().UpdateShellDescriptor(
                            0,
                            shellDescriptor.Features,
                            shellDescriptor.Parameters);
                    }
                }
            }



            // in effect "pump messages" see PostMessage circa 1980
            while (_processingEngine.AreTasksPending())
            {
                _processingEngine.ExecuteNextTask();
            }

            // creating a standalone environment.
            // in theory this environment can be used to resolve any normal components by interface, and those
            // components will exist entirely in isolation - no crossover between the safemode container currently in effect

            // must mark state as Running - otherwise standalone enviro is created "for setup"
            shellSettings.State = TenantState.Running;
            using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) {
                try {
                    executionId = CreateTenantData(context, environment);
                }
                catch {
                    environment.Resolve <ITransactionManager>().Cancel();
                    throw;
                }
            }

            _shellSettingsManager.SaveSettings(shellSettings);

            return(executionId);
        }
Ejemplo n.º 12
0
        public ShellContext CreateShellContext(ShellSettings settings)
        {
            Logger.DebugFormat("Creating shell context for tenant {0}", settings.Name);

            var knownDescriptor = shellDescriptorCache.Fetch(settings.Name);

            if (knownDescriptor == null)
            {
                Logger.Info("No descriptor cached. Starting with minimum components.");
                var multiTenancy = Convert.ToBoolean(ConfigurationManager.AppSettings["CMS.MultiTenancy"]);
                knownDescriptor = MinimumShellDescriptor(multiTenancy);
            }

            if (!string.IsNullOrEmpty(settings.DataProvider))
            {
                var provider = CMSConfigurationSection.Instance.Data.Providers[settings.DataProvider];
                if (provider != null)
                {
                    if (knownDescriptor.Features.All(x => x.Name != provider.Feature))
                    {
                        knownDescriptor.Features.Insert(1, new ShellFeature {
                            Name = provider.Feature
                        });
                    }
                }
            }

            var blueprint  = compositionStrategy.Compose(settings, knownDescriptor);
            var shellScope = shellContainerFactory.CreateContainer(settings, blueprint);

            ShellDescriptor currentDescriptor;

            using (var standaloneEnvironment = shellScope.CreateWorkContextScope())
            {
                var shellDescriptorManager = standaloneEnvironment.Resolve <IShellDescriptorManager>();
                currentDescriptor = shellDescriptorManager.GetShellDescriptor();

                if (currentDescriptor == null)
                {
                    shellDescriptorManager.UpdateShellDescriptor(0, knownDescriptor.Features, false);
                }
                else
                {
                    // Detect new auto activated features
                    if (knownDescriptor.SerialNumber == currentDescriptor.SerialNumber)
                    {
                        var features = new List <ShellFeature>(currentDescriptor.Features);
                        var hasNew   = false;
                        foreach (var feature in knownDescriptor.Features)
                        {
                            if (features.All(x => x.Name != feature.Name))
                            {
                                features.Add(feature);
                                hasNew = true;
                            }
                        }

                        if (hasNew)
                        {
                            currentDescriptor.Features = features;
                            shellDescriptorManager.UpdateShellDescriptor(currentDescriptor.SerialNumber, features, false);
                        }
                    }
                }
            }

            if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber)
            {
                Logger.Info("Newer descriptor obtained. Rebuilding shell container.");

                shellDescriptorCache.Store(settings.Name, currentDescriptor);
                blueprint = compositionStrategy.Compose(settings, currentDescriptor);
                shellScope.Dispose();
                shellScope = shellContainerFactory.CreateContainer(settings, blueprint);
            }

            if (currentDescriptor == null)
            {
                currentDescriptor = knownDescriptor;
            }

            return(new ShellContext
            {
                Settings = settings,
                Descriptor = currentDescriptor,
                Blueprint = blueprint,
                LifetimeScope = shellScope,
                Shell = shellScope.Resolve <ICMSShell>(),
            });
        }
Ejemplo n.º 13
0
        private string SetupInternal(SetupContext context)
        {
            string executionId;

            Logger.Information("Running setup for tenant '{0}'.", _shellSettings.Name);

            // The vanilla Orchard distibution has the following features enabled.
            string[] hardcoded =
            {
                // Framework
                "Orchard.Framework",
                // Core
                "Common",           "Containers",             "Contents",       "Dashboard",     "Feeds",         "Navigation",      "Scheduling", "Settings", "Shapes", "Title",
                // Modules
                "Orchard.Pages",    "Orchard.ContentPicker",  "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules",
                "PackagingServices","Orchard.Packaging",      "Gallery",        "Orchard.Recipes"
            };

            context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList();

            // Set shell state to "Initializing" so that subsequent HTTP requests are responded to with "Service Unavailable" while Orchard is setting up.
            _shellSettings.State = TenantState.Initializing;

            var shellSettings = new ShellSettings(_shellSettings);

            if (String.IsNullOrEmpty(shellSettings.DataProvider))
            {
                shellSettings.DataProvider         = context.DatabaseProvider;
                shellSettings.DataConnectionString = context.DatabaseConnectionString;
                shellSettings.DataTablePrefix      = context.DatabaseTablePrefix;
            }

            shellSettings.EncryptionAlgorithm = "AES";

            // Randomly generated key.
            shellSettings.EncryptionKey = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString();
            shellSettings.HashAlgorithm = "HMACSHA256";

            // Randomly generated key.
            shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString();

            var shellDescriptor = new ShellDescriptor {
                Features = context.EnabledFeatures.Select(name => new ShellFeature {
                    Name = name
                })
            };

            var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor);

            // Initialize database explicitly, and store shell descriptor.
            using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) {
                using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) {
                    // Check if the database is already created (in case an exception occured in the second phase).
                    var schemaBuilder       = new SchemaBuilder(environment.Resolve <IDataMigrationInterpreter>());
                    var installationPresent = true;
                    try {
                        var tablePrefix = String.IsNullOrEmpty(shellSettings.DataTablePrefix) ? "" : shellSettings.DataTablePrefix + "_";
                        schemaBuilder.ExecuteSql("SELECT * FROM " + tablePrefix + "Settings_ShellDescriptorRecord");
                    }
                    catch {
                        installationPresent = false;
                    }

                    if (installationPresent)
                    {
                        throw new OrchardException(T("A previous Orchard installation was detected in this database with this table prefix."));
                    }

                    // Workaround to avoid some Transaction issue for PostgreSQL.
                    environment.Resolve <ITransactionManager>().RequireNew();

                    schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table
                                              .Column <int>("Id", column => column.PrimaryKey().Identity())
                                              .Column <string>("DataMigrationClass")
                                              .Column <int>("Version"));

                    schemaBuilder.AlterTable("Orchard_Framework_DataMigrationRecord",
                                             table => table.AddUniqueConstraint("UC_DMR_DataMigrationClass_Version", "DataMigrationClass", "Version"));

                    var dataMigrationManager = environment.Resolve <IDataMigrationManager>();
                    dataMigrationManager.Update("Settings");

                    foreach (var feature in context.EnabledFeatures)
                    {
                        dataMigrationManager.Update(feature);
                    }

                    environment.Resolve <IShellDescriptorManager>().UpdateShellDescriptor(
                        0,
                        shellDescriptor.Features,
                        shellDescriptor.Parameters);
                }
            }

            // In effect "pump messages" see PostMessage circa 1980.
            while (_processingEngine.AreTasksPending())
            {
                _processingEngine.ExecuteNextTask();
            }

            // Creating a standalone environment.
            // in theory this environment can be used to resolve any normal components by interface, and those
            // components will exist entirely in isolation - no crossover between the safemode container currently in effect.
            using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) {
                try {
                    executionId = CreateTenantData(context, environment);
                }
                catch {
                    environment.Resolve <ITransactionManager>().Cancel();
                    throw;
                }
            }

            _shellSettingsManager.SaveSettings(shellSettings);
            return(executionId);
        }