/// <summary> /// Adds a redis configuration with the given <paramref name="configurationKey"/>. /// </summary> /// <param name="part">The builder instance.</param> /// <param name="configurationKey"> /// The configuration key which can be used to refernce this configuration by a redis cache handle or backplate. /// </param> /// <param name="connectionString">The redis connection string.</param> /// <returns>The configuration builder.</returns> /// <exception cref="System.ArgumentNullException"> /// If <paramref name="configurationKey"/> or <paramref name="connectionString"/> are null. /// </exception> public static ConfigurationBuilderCachePart WithRedisConfiguration(this ConfigurationBuilderCachePart part, string configurationKey, string connectionString) { NotNullOrWhiteSpace(configurationKey, nameof(configurationKey)); NotNullOrWhiteSpace(connectionString, nameof(connectionString)); RedisConfigurations.AddConfiguration(new RedisConfiguration(configurationKey, connectionString)); return(part); }
/// <summary> /// Adds a redis configuration with the given <paramref name="configurationKey"/>. /// </summary> /// <param name="part">The builder instance.</param> /// <param name="configurationKey"> /// The configuration key which can be used to refernce this configuration by a redis cache handle or backplane. /// </param> /// <param name="connectionString">The redis connection string.</param> /// <param name="database">The redis database to be used.</param> /// <param name="enableKeyspaceNotifications"> /// Enables keyspace notifications to react on eviction/expiration of items. /// Make sure that all servers are configured correctly and 'notify-keyspace-events' is at least set to 'Exe', otherwise CacheManager will not retrieve any events. /// See <see href="https://redis.io/topics/notifications#configuration"/> for configuration details. /// </param> /// <returns>The configuration builder.</returns> /// <exception cref="System.ArgumentNullException"> /// If <paramref name="configurationKey"/> or <paramref name="connectionString"/> are null. /// </exception> public static ConfigurationBuilderCachePart WithRedisConfiguration(this ConfigurationBuilderCachePart part, string configurationKey, string connectionString, int database = 0, bool enableKeyspaceNotifications = false) { NotNullOrWhiteSpace(configurationKey, nameof(configurationKey)); NotNullOrWhiteSpace(connectionString, nameof(connectionString)); RedisConfigurations.AddConfiguration(new RedisConfiguration(configurationKey, connectionString, database, enableKeyspaceNotifications)); return(part); }
/// <summary> /// Adds a redis configuration with the given <paramref name="configurationKey"/>. /// </summary> /// <param name="part">The builder instance.</param> /// <param name="configurationKey"> /// The configuration key which can be used to refernce this configuration by a redis cache handle or backplate. /// </param> /// <param name="configuration">The redis configuration object.</param> /// <returns>The configuration builder.</returns> /// <exception cref="System.ArgumentNullException">If <paramref name="configuration"/> or <paramref name="configurationKey"/> are null.</exception> public static ConfigurationBuilderCachePart WithRedisConfiguration(this ConfigurationBuilderCachePart part, string configurationKey, Action <RedisConfigurationBuilder> configuration) { NotNull(configuration, nameof(configuration)); var builder = new RedisConfigurationBuilder(configurationKey); configuration(builder); RedisConfigurations.AddConfiguration(builder.Build()); return(part); }
/// <summary> /// Adds a redis configuration. /// </summary> /// <param name="part">The part.</param> /// <param name="configurationKey"> /// The configuration key which has to match with the cache handle name. /// </param> /// <param name="config">The redis configuration object.</param> /// <returns>The configuration builder.</returns> /// <exception cref="System.ArgumentNullException">If config is null.</exception> public static ConfigurationBuilderCachePart WithRedisConfiguration(this ConfigurationBuilderCachePart part, string configurationKey, Action <RedisConfigurationBuilder> config) { if (config == null) { throw new ArgumentNullException("config"); } var builder = new RedisConfigurationBuilder(configurationKey); config(builder); RedisConfigurations.AddConfiguration(builder.Build()); return(part); }
/// <summary> /// Adds a redis configuration. /// </summary> /// <param name="part">The part.</param> /// <param name="configurationKey"> /// The configuration key which has to match with the cache handle name. /// </param> /// <param name="connectionString">The redis connection string.</param> /// <returns>The configuration builder.</returns> /// <exception cref="System.ArgumentNullException"> /// If configurationKey or connectionString are null. /// </exception> public static ConfigurationBuilderCachePart WithRedisConfiguration(this ConfigurationBuilderCachePart part, string configurationKey, string connectionString) { if (string.IsNullOrWhiteSpace(configurationKey)) { throw new ArgumentNullException("configurationKey"); } if (string.IsNullOrWhiteSpace(connectionString)) { throw new ArgumentNullException("connectionString"); } RedisConfigurations.AddConfiguration(new RedisConfiguration(configurationKey, connectionString)); return(part); }
private static void InitializePlatform( IAppBuilder app, IUnityContainer container, IPathMapper pathMapper, string connectionString, HangfireLauncher hangfireLauncher, string modulesPath, ModuleInitializerOptions moduleInitializerOptions) { container.RegisterType <ICurrentUser, CurrentUser>(new HttpContextLifetimeManager()); container.RegisterType <IUserNameResolver, UserNameResolver>(); #region Setup database using (var db = new SecurityDbContext(connectionString)) { new IdentityDatabaseInitializer().InitializeDatabase(db); } using (var context = new PlatformRepository(connectionString, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor())) { new PlatformDatabaseInitializer().InitializeDatabase(context); } hangfireLauncher.ConfigureDatabase(); #endregion Func <IPlatformRepository> platformRepositoryFactory = () => new PlatformRepository(connectionString, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor()); container.RegisterType <IPlatformRepository>(new InjectionFactory(c => platformRepositoryFactory())); container.RegisterInstance(platformRepositoryFactory); var moduleCatalog = container.Resolve <IModuleCatalog>(); #region Caching //Cure for System.Runtime.Caching.MemoryCache freezing //https://www.zpqrtbnk.net/posts/appdomains-threads-cultureinfos-and-paracetamol app.SanitizeThreadCulture(); ICacheManager <object> cacheManager = null; var redisConnectionString = ConfigurationHelper.GetConnectionStringValue("RedisConnectionString"); //Try to load cache configuration from web.config first //Should be aware to using Web cache cache handle because it not worked in native threads. (Hangfire jobs) if (ConfigurationManager.GetSection(CacheManagerSection.DefaultSectionName) is CacheManagerSection cacheManagerSection) { CacheManagerConfiguration configuration = null; var defaultCacheManager = cacheManagerSection.CacheManagers.FirstOrDefault(p => p.Name.EqualsInvariant("platformCache")); if (defaultCacheManager != null) { configuration = ConfigurationBuilder.LoadConfiguration(defaultCacheManager.Name); } var redisCacheManager = cacheManagerSection.CacheManagers.FirstOrDefault(p => p.Name.EqualsInvariant("redisPlatformCache")); if (redisConnectionString != null && redisCacheManager != null) { configuration = ConfigurationBuilder.LoadConfiguration(redisCacheManager.Name); } if (configuration != null) { configuration.LoggerFactoryType = typeof(CacheManagerLoggerFactory); configuration.LoggerFactoryTypeArguments = new object[] { container.Resolve <ILog>() }; cacheManager = CacheFactory.FromConfiguration <object>(configuration); } } // Create a default cache manager if there is no any others if (cacheManager == null) { cacheManager = CacheFactory.Build("platformCache", settings => { settings.WithUpdateMode(CacheUpdateMode.Up) .WithSystemRuntimeCacheHandle("memCacheHandle") .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromMinutes(5)); }); } container.RegisterInstance(cacheManager); #endregion #region Settings var platformModuleManifest = new ModuleManifest { Id = "VirtoCommerce.Platform", Version = PlatformVersion.CurrentVersion.ToString(), PlatformVersion = PlatformVersion.CurrentVersion.ToString(), Settings = new[] { new ModuleSettingsGroup { Name = "Platform|Notifications|SendGrid", Settings = new [] { new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SendGrid.ApiKey", ValueType = ModuleSetting.TypeSecureString, Title = "SendGrid API key", Description = "Your SendGrid API key" } } }, new ModuleSettingsGroup { Name = "Platform|Notifications|SendingJob", Settings = new [] { new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SendingJob.TakeCount", ValueType = ModuleSetting.TypeInteger, Title = "Job Take Count", Description = "Take count for sending job" } } }, new ModuleSettingsGroup { Name = "Platform|Notifications|SmtpClient", Settings = new [] { new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SmptClient.Host", ValueType = ModuleSetting.TypeString, Title = "Smtp server host", Description = "Smtp server host" }, new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SmptClient.Port", ValueType = ModuleSetting.TypeInteger, Title = "Smtp server port", Description = "Smtp server port" }, new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SmptClient.Login", ValueType = ModuleSetting.TypeString, Title = "Smtp server login", Description = "Smtp server login" }, new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SmptClient.Password", ValueType = ModuleSetting.TypeSecureString, Title = "Smtp server password", Description = "Smtp server password" }, new ModuleSetting { Name = "VirtoCommerce.Platform.Notifications.SmptClient.UseSsl", ValueType = ModuleSetting.TypeBoolean, Title = "Use SSL", Description = "Use secure connection" }, } }, new ModuleSettingsGroup { Name = "Platform|Security", Settings = new [] { new ModuleSetting { Name = "VirtoCommerce.Platform.Security.AccountTypes", ValueType = ModuleSetting.TypeString, Title = "Account types", Description = "Dictionary for possible account types", IsArray = true, ArrayValues = Enum.GetNames(typeof(AccountType)), DefaultValue = AccountType.Manager.ToString() } } }, new ModuleSettingsGroup { Name = "Platform|User Profile", Settings = new[] { new ModuleSetting { Name = "VirtoCommerce.Platform.UI.MainMenu.State", ValueType = ModuleSetting.TypeJson, Title = "Persisted state of main menu" }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.Language", ValueType = ModuleSetting.TypeString, Title = "Language", Description = "Default language (two letter code from ISO 639-1, case-insensitive). Example: en, de", DefaultValue = "en" }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.RegionalFormat", ValueType = ModuleSetting.TypeString, Title = "Regional format", Description = "Default regional format (CLDR locale code, with dash or underscore as delemiter, case-insensitive). Example: en, en_US, sr_Cyrl, sr_Cyrl_RS", DefaultValue = "en" }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.TimeZone", ValueType = ModuleSetting.TypeString, Title = "Time zone", Description = "Default time zone (IANA time zone name [tz database], exactly as in database, case-sensitive). Examples: America/New_York, Europe/Moscow" }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.ShowMeridian", ValueType = ModuleSetting.TypeBoolean, Title = "Meridian labels based on user preferences", Description = "When set to true (by default), system will display time in format like '12 hour format' when possible", DefaultValue = true.ToString() }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.UseTimeAgo", ValueType = ModuleSetting.TypeBoolean, Title = "Use time ago format when is possible", Description = "When set to true (by default), system will display date in format like 'a few seconds ago' when possible", DefaultValue = true.ToString() }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.FullDateThreshold", ValueType = ModuleSetting.TypeInteger, Title = "Full date threshold", Description = "Number of units after time ago format will be switched to full date format" }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.FullDateThresholdUnit", ValueType = ModuleSetting.TypeString, Title = "Full date threshold unit", Description = "Unit of full date threshold", DefaultValue = "Never", AllowedValues = new[] { "Never", "Seconds", "Minutes", "Hours", "Days", "Weeks", "Months", "Quarters", "Years" } }, new ModuleSetting { Name = "VirtoCommerce.Platform.UI.FourDecimalsInMoney", ValueType = ModuleSetting.TypeBoolean, Title = "Show 4 decimal digits for money", Description = "Set to true to show 4 decimal digits for money. By default - false, 2 decimal digits are shown.", DefaultValue = "false", }, } }, new ModuleSettingsGroup { Name = "Platform|User Interface", Settings = new[] { new ModuleSetting { Name = "VirtoCommerce.Platform.UI.Customization", ValueType = ModuleSetting.TypeJson, Title = "Customization", Description = "JSON contains personalization settings of manager UI", DefaultValue = "{\n" + " \"title\": \"Virto Commerce\",\n" + " \"logo\": \"Content/themes/main/images/logo.png\",\n" + " \"contrast_logo\": \"Content/themes/main/images/contrast-logo.png\",\n" + " \"favicon\": \"favicon.ico\"\n" + "}" } } } } }; var settingsManager = new SettingsManager(moduleCatalog, platformRepositoryFactory, cacheManager, new[] { new ManifestModuleInfo(platformModuleManifest) }); container.RegisterInstance <ISettingsManager>(settingsManager); #endregion #region Dynamic Properties container.RegisterType <IDynamicPropertyService, DynamicPropertyService>(new ContainerControlledLifetimeManager()); #endregion #region Notifications // Redis if (!string.IsNullOrEmpty(redisConnectionString)) { // Cache RedisConfigurations.AddConfiguration(new RedisConfiguration("redisConnectionString", redisConnectionString)); // SignalR // https://stackoverflow.com/questions/29885470/signalr-scaleout-on-azure-rediscache-connection-issues GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(redisConnectionString, "VirtoCommerce.Platform.SignalR")); } // SignalR var tempCounterManager = new TempPerformanceCounterManager(); GlobalHost.DependencyResolver.Register(typeof(IPerformanceCounterManager), () => tempCounterManager); var hubConfiguration = new HubConfiguration { EnableJavaScriptProxies = false }; app.MapSignalR("/" + moduleInitializerOptions.RoutePrefix + "signalr", hubConfiguration); var hubSignalR = GlobalHost.ConnectionManager.GetHubContext <ClientPushHub>(); var notifier = new InMemoryPushNotificationManager(hubSignalR); container.RegisterInstance <IPushNotificationManager>(notifier); var resolver = new LiquidNotificationTemplateResolver(); container.RegisterInstance <INotificationTemplateResolver>(resolver); var notificationTemplateService = new NotificationTemplateServiceImpl(platformRepositoryFactory); container.RegisterInstance <INotificationTemplateService>(notificationTemplateService); var notificationManager = new NotificationManager(resolver, platformRepositoryFactory, notificationTemplateService); container.RegisterInstance <INotificationManager>(notificationManager); IEmailNotificationSendingGateway emailNotificationSendingGateway = null; var emailNotificationSendingGatewayName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:Gateway", "Default"); if (string.Equals(emailNotificationSendingGatewayName, "Default", StringComparison.OrdinalIgnoreCase)) { emailNotificationSendingGateway = new DefaultSmtpEmailNotificationSendingGateway(settingsManager); } else if (string.Equals(emailNotificationSendingGatewayName, "SendGrid", StringComparison.OrdinalIgnoreCase)) { emailNotificationSendingGateway = new SendGridEmailNotificationSendingGateway(settingsManager); } if (emailNotificationSendingGateway != null) { container.RegisterInstance(emailNotificationSendingGateway); } ISmsNotificationSendingGateway smsNotificationSendingGateway = null; var smsNotificationSendingGatewayName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway", "Default"); if (smsNotificationSendingGatewayName.EqualsInvariant("Default")) { smsNotificationSendingGateway = new DefaultSmsNotificationSendingGateway(); } else if (smsNotificationSendingGatewayName.EqualsInvariant("Twilio")) { smsNotificationSendingGateway = new TwilioSmsNotificationSendingGateway(new TwilioSmsGatewayOptions { AccountId = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountId"), AccountPassword = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountPassword"), Sender = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:Sender"), }); } else if (smsNotificationSendingGatewayName.EqualsInvariant("ASPSMS")) { smsNotificationSendingGateway = new AspsmsSmsNotificationSendingGateway(new AspsmsSmsGatewayOptions { AccountId = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountId"), AccountPassword = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountPassword"), Sender = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:Sender"), JsonApiUri = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:ASPSMS:JsonApiUri"), }); } if (smsNotificationSendingGateway != null) { container.RegisterInstance(smsNotificationSendingGateway); } #endregion #region Assets var blobConnectionString = BlobConnectionString.Parse(ConfigurationHelper.GetConnectionStringValue("AssetsConnectionString")); if (string.Equals(blobConnectionString.Provider, FileSystemBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase)) { var fileSystemBlobProvider = new FileSystemBlobProvider(NormalizePath(pathMapper, blobConnectionString.RootPath), blobConnectionString.PublicUrl); container.RegisterInstance <IBlobStorageProvider>(fileSystemBlobProvider); container.RegisterInstance <IBlobUrlResolver>(fileSystemBlobProvider); } else if (string.Equals(blobConnectionString.Provider, AzureBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase)) { var azureBlobProvider = new AzureBlobProvider(blobConnectionString.ConnectionString, blobConnectionString.CdnUrl); container.RegisterInstance <IBlobStorageProvider>(azureBlobProvider); container.RegisterInstance <IBlobUrlResolver>(azureBlobProvider); } container.RegisterType <IAssetEntryService, AssetEntryService>(new ContainerControlledLifetimeManager()); container.RegisterType <IAssetEntrySearchService, AssetEntryService>(new ContainerControlledLifetimeManager()); #endregion #region Modularity var modulesDataSources = ConfigurationHelper.SplitAppSettingsStringValue("VirtoCommerce:ModulesDataSources"); var externalModuleCatalog = new ExternalManifestModuleCatalog(moduleCatalog.Modules, modulesDataSources, container.Resolve <ILog>()); container.RegisterType <ModulesController>(new InjectionConstructor(externalModuleCatalog, new ModuleInstaller(modulesPath, externalModuleCatalog), notifier, container.Resolve <IUserNameResolver>(), settingsManager)); #endregion #region ChangeLogging var changeLogService = new ChangeLogService(platformRepositoryFactory); container.RegisterInstance <IChangeLogService>(changeLogService); #endregion #region Security container.RegisterInstance <IPermissionScopeService>(new PermissionScopeService()); container.RegisterType <IRoleManagementService, RoleManagementService>(new ContainerControlledLifetimeManager()); var apiAccountProvider = new ApiAccountProvider(platformRepositoryFactory, cacheManager); container.RegisterInstance <IApiAccountProvider>(apiAccountProvider); container.RegisterType <IClaimsIdentityProvider, ApplicationClaimsIdentityProvider>(new ContainerControlledLifetimeManager()); container.RegisterInstance(app.GetDataProtectionProvider()); container.RegisterType <SecurityDbContext>(new InjectionConstructor(connectionString)); container.RegisterType <IUserStore <ApplicationUser>, ApplicationUserStore>(); container.RegisterType <IAuthenticationManager>(new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication)); container.RegisterType <ApplicationUserManager>(); container.RegisterType <ApplicationSignInManager>(); var nonEditableUsers = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:NonEditableUsers", string.Empty); container.RegisterInstance <ISecurityOptions>(new SecurityOptions(nonEditableUsers)); container.RegisterType <ISecurityService, SecurityService>(); container.RegisterType <IPasswordCheckService, PasswordCheckService>(); #endregion #region ExportImport container.RegisterType <IPlatformExportImportManager, PlatformExportImportManager>(); #endregion #region Serialization container.RegisterType <IExpressionSerializer, XmlExpressionSerializer>(); #endregion #region Events var inProcessBus = new InProcessBus(); container.RegisterInstance <IHandlerRegistrar>(inProcessBus); container.RegisterInstance <IEventPublisher>(inProcessBus); inProcessBus.RegisterHandler <UserChangedEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message)); inProcessBus.RegisterHandler <UserPasswordChangedEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message)); inProcessBus.RegisterHandler <UserResetPasswordEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message)); #endregion }
public static void SetupContainer(IAppBuilder app, IUnityContainer container, IPathMapper pathMapper, string virtualRoot, string routePrefix, string modulesPhysicalPath) { container.RegisterInstance(app); var moduleInitializerOptions = (ModuleInitializerOptions)container.Resolve <IModuleInitializerOptions>(); moduleInitializerOptions.VirtualRoot = virtualRoot; moduleInitializerOptions.RoutePrefix = routePrefix; //Initialize Platform dependencies var connectionString = ConfigurationHelper.GetConnectionStringValue("VirtoCommerce"); var hangfireOptions = new HangfireOptions { StartServer = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Jobs.Enabled", true), JobStorageType = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Jobs.StorageType", "Memory"), DatabaseConnectionString = connectionString, WorkerCount = ConfigurationHelper.GetNullableAppSettingsValue("VirtoCommerce:Jobs.WorkerCount", (int?)null) }; var hangfireLauncher = new HangfireLauncher(hangfireOptions); InitializePlatform(app, container, pathMapper, connectionString, hangfireLauncher, modulesPhysicalPath); var moduleManager = container.Resolve <IModuleManager>(); var moduleCatalog = container.Resolve <IModuleCatalog>(); var applicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase.EnsureEndSeparator(); // Register URL rewriter for platform scripts var scriptsPhysicalPath = pathMapper.MapPath(VirtualRoot + "/Scripts").EnsureEndSeparator(); var scriptsRelativePath = MakeRelativePath(applicationBase, scriptsPhysicalPath); var platformUrlRewriterOptions = new UrlRewriterOptions(); platformUrlRewriterOptions.Items.Add(PathString.FromUriComponent("/$(Platform)/Scripts"), ""); app.Use <UrlRewriterOwinMiddleware>(platformUrlRewriterOptions); app.UseStaticFiles(new StaticFileOptions { FileSystem = new Microsoft.Owin.FileSystems.PhysicalFileSystem(scriptsRelativePath) }); // Register URL rewriter before modules initialization if (Directory.Exists(modulesPhysicalPath)) { var modulesRelativePath = MakeRelativePath(applicationBase, modulesPhysicalPath); var urlRewriterOptions = new UrlRewriterOptions(); foreach (var module in moduleCatalog.Modules.OfType <ManifestModuleInfo>()) { var urlRewriteKey = string.Format(CultureInfo.InvariantCulture, "/Modules/$({0})", module.ModuleName); var urlRewriteValue = MakeRelativePath(modulesPhysicalPath, module.FullPhysicalPath); urlRewriterOptions.Items.Add(PathString.FromUriComponent(urlRewriteKey), "/" + urlRewriteValue); moduleInitializerOptions.ModuleDirectories.Add(module.ModuleName, module.FullPhysicalPath); } app.Use <UrlRewriterOwinMiddleware>(urlRewriterOptions); app.UseStaticFiles(new StaticFileOptions { FileSystem = new Microsoft.Owin.FileSystems.PhysicalFileSystem(modulesRelativePath) }); } container.RegisterInstance(GlobalConfiguration.Configuration); // Ensure all modules are loaded foreach (var module in moduleCatalog.Modules.OfType <ManifestModuleInfo>().Where(x => x.State == ModuleState.NotStarted)) { moduleManager.LoadModule(module.ModuleName); } SwaggerConfig.RegisterRoutes(container); // Post-initialize // Register MVC areas unless running in the Web Platform Installer mode if (IsApplication) { AreaRegistration.RegisterAllAreas(); } // Register other MVC resources GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); if (IsApplication) { RouteConfig.RegisterRoutes(RouteTable.Routes); } BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); // Security OWIN configuration var authenticationOptions = new Core.Security.AuthenticationOptions { CookiesEnabled = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Cookies.Enabled", true), CookiesValidateInterval = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Cookies.ValidateInterval", TimeSpan.FromDays(1)), BearerTokensEnabled = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:BearerTokens.Enabled", true), BearerTokensExpireTimeSpan = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:BearerTokens.AccessTokenExpireTimeSpan", TimeSpan.FromHours(1)), HmacEnabled = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Hmac.Enabled", true), HmacSignatureValidityPeriod = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Hmac.SignatureValidityPeriod", TimeSpan.FromMinutes(20)), ApiKeysEnabled = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:ApiKeys.Enabled", true), ApiKeysHttpHeaderName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:ApiKeys.HttpHeaderName", "api_key"), ApiKeysQueryStringParameterName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:ApiKeys.QueryStringParameterName", "api_key"), }; OwinConfig.Configure(app, container, authenticationOptions); hangfireLauncher.ConfigureOwin(app, container); RecurringJob.AddOrUpdate <SendNotificationsJobs>("SendNotificationsJob", x => x.Process(), "*/1 * * * *"); var notificationManager = container.Resolve <INotificationManager>(); notificationManager.RegisterNotificationType(() => new RegistrationEmailNotification(container.Resolve <IEmailNotificationSendingGateway>()) { DisplayName = "Registration notification", Description = "This notification is sent by email to a client when he finishes registration", NotificationTemplate = new NotificationTemplate { Subject = PlatformNotificationResource.RegistrationNotificationSubject, Body = PlatformNotificationResource.RegistrationNotificationBody, Language = "en-US", } }); notificationManager.RegisterNotificationType(() => new ResetPasswordEmailNotification(container.Resolve <IEmailNotificationSendingGateway>()) { DisplayName = "Reset password notification", Description = "This notification is sent by email to a client upon reset password request", NotificationTemplate = new NotificationTemplate { Subject = PlatformNotificationResource.ResetPasswordNotificationSubject, Body = PlatformNotificationResource.ResetPasswordNotificationBody, Language = "en-US", } }); notificationManager.RegisterNotificationType(() => new TwoFactorEmailNotification(container.Resolve <IEmailNotificationSendingGateway>()) { DisplayName = "Two factor authentication", Description = "This notification contains a security token for two factor authentication", NotificationTemplate = new NotificationTemplate { Subject = PlatformNotificationResource.TwoFactorNotificationSubject, Body = PlatformNotificationResource.TwoFactorNotificationBody, Language = "en-US", } }); notificationManager.RegisterNotificationType(() => new TwoFactorSmsNotification(container.Resolve <ISmsNotificationSendingGateway>()) { DisplayName = "Two factor authentication", Description = "This notification contains a security token for two factor authentication", NotificationTemplate = new NotificationTemplate { Subject = PlatformNotificationResource.TwoFactorNotificationSubject, Body = PlatformNotificationResource.TwoFactorNotificationBody, Language = "en-US", } }); //Get initialized modules list sorted by dependency order var postInitializeModules = moduleCatalog.CompleteListWithDependencies(moduleCatalog.Modules.OfType <ManifestModuleInfo>()) .Where(m => m.ModuleInstance != null && m.State == ModuleState.Initialized) .ToArray(); foreach (var module in postInitializeModules) { moduleManager.PostInitializeModule(module); } var redisConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"]; // Redis if (redisConnectionString != null && !string.IsNullOrEmpty(redisConnectionString.ConnectionString)) { // Cache RedisConfigurations.AddConfiguration(new RedisConfiguration("redisConnectionString", redisConnectionString.ConnectionString)); // SignalR // https://stackoverflow.com/questions/29885470/signalr-scaleout-on-azure-rediscache-connection-issues GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(redisConnectionString.ConnectionString, "VirtoCommerce.Platform.SignalR")); } // SignalR var tempCounterManager = new TempPerformanceCounterManager(); GlobalHost.DependencyResolver.Register(typeof(IPerformanceCounterManager), () => tempCounterManager); var hubConfiguration = new HubConfiguration { EnableJavaScriptProxies = false }; app.MapSignalR("/" + moduleInitializerOptions.RoutePrefix + "signalr", hubConfiguration); // Initialize InstrumentationKey from EnvironmentVariable var appInsightKey = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY"); if (!string.IsNullOrEmpty(appInsightKey)) { TelemetryConfiguration.Active.InstrumentationKey = appInsightKey; } }