private void DisposeOldWebInterfaceServer() { const string LOG_TAG_PREFIX = "ApplicationServer::DisposeOldHttpServer::"; try { using (var srv = this._webHandler) { this._webHandler = null; } } catch (Exception ex) { this.Logger .Log(msg: ex.GetBaseException() ?? ex, tag: LOG_TAG_PREFIX + "Dispose", categories: LoggerFacadeCategories.Errors | LoggerFacadeCategories.Debug); } }
private void StartServer() { const string LOG_TAG_PREFIX = "ApplicationServer::StartServer::"; AggregateException ex = null; this.ReinitTrustedCompositionCatalog(); // assemblies with services { var serviceDir = new DirectoryInfo(Path.Combine(this.WorkingDirectory, "services")).CreateDirectoryDeep(); this.LoadAndAddTrustedAssemblies(serviceDir.GetFiles("*.dll"), LOG_TAG_PREFIX); } // assemblies with functions { var funcDir = new DirectoryInfo(Path.Combine(this.WorkingDirectory, "funcs")).CreateDirectoryDeep(); this.LoadAndAddTrustedAssemblies(funcDir.GetFiles("*.dll"), LOG_TAG_PREFIX); } // web interface { IList <Assembly> webInterfaceAssemblies = new SynchronizedCollection <Assembly>(); var webDir = new DirectoryInfo(Path.Combine(this.WorkingDirectory, "web")).CreateDirectoryDeep(); this.LoadAndAddTrustedAssemblies(webDir.GetFiles("*.dll"), LOG_TAG_PREFIX); try { this.DisposeOldWebInterfaceServer(); //TODO read from configuration var newWebInterfaceServer = ServiceLocator.Current.GetInstance <IHttpServer>(); { // HTTPs ? { bool?useHttps; this.StartupConfig .TryGetValue <bool?>(category: CONFIG_CATEGORY_WEBINTERFACE, name: CONFIG_VALUE_USE_HTTPS, value: out useHttps, defaultVal: DEFAULT_CONFIG_VALUE_USE_HTTPS); newWebInterfaceServer.UseSecureHttp = useHttps ?? DEFAULT_CONFIG_VALUE_USE_HTTPS; } // TCP port { int?port; this.StartupConfig .TryGetValue <int?>(category: CONFIG_CATEGORY_WEBINTERFACE, name: CONFIG_VALUE_PORT, value: out port, defaultVal: DEFAULT_CONFIG_VALUE_WEBINTERFACE_PORT); newWebInterfaceServer.Port = port ?? DEFAULT_CONFIG_VALUE_WEBINTERFACE_PORT; } if (newWebInterfaceServer.UseSecureHttp) { // SSL thumbprint { newWebInterfaceServer.SetSslCertificateByThumbprint(this.StartupConfig .GetValue <IEnumerable <char> >(category: CONFIG_CATEGORY_WEBINTERFACE, name: CONFIG_VALUE_SSL_THUMBPRINT)); } } } var newHandler = new WebInterfaceHandler(this, newWebInterfaceServer); this._webHandler = newHandler; newHandler.Start(); } catch (Exception e) { this.Logger .Log(msg: e.GetBaseException() ?? e, tag: LOG_TAG_PREFIX + "WebInterface", categories: LoggerFacadeCategories.Errors); this.DisposeOldWebInterfaceServer(); } } var moduleList = this.Modules; if (moduleList != null) { ex = moduleList.OfType <global::System.IDisposable>() .ForAllAsync(ctx => { var m = ctx.Item; var doDispose = true; var dispObj = m as ITMDisposable; if (dispObj != null) { doDispose = !dispObj.IsDisposed; } if (doDispose) { m.Dispose(); } }, throwExceptions: false); } if (ex != null) { this.Logger .Log(msg: ex, tag: LOG_TAG_PREFIX + "UnloadOldModules", categories: LoggerFacadeCategories.Errors); } IList <IAppServerModule> newModules = new SynchronizedCollection <IAppServerModule>(); var modDir = new DirectoryInfo(Path.Combine(this.WorkingDirectory, "modules")).CreateDirectoryDeep(); { ex = modDir.GetFiles("*.dll") .ForAllAsync(ctx => { var f = ctx.Item; var trustedCatalog = ctx.State.CompositionCatalog.Clone(cloneCatalogData: true); var asmName = AssemblyName.GetAssemblyName(f.FullName); if (!trustedCatalog.IsTrustedAssembly(asmName)) { #if DEBUG var s = string.Format("INSERT INTO [Security].[TrustedAssemblies] (TrustedAssemblyKey, Name) VALUES (0x{0}, N'{1}');", asmName.GetPublicKey().AsHexString(), asmName.FullName); #endif ctx.State .Logger .Log(categories: LoggerFacadeCategories.Warnings, msg: string.Format("'{0}' is no trusted module!", f.FullName)); return; } var asmBlob = File.ReadAllBytes(f.FullName); var asm = Assembly.Load(asmBlob); trustedCatalog.AddAssembly(asm); CompositionContainer container; DelegateServiceLocator serviceLocator; { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(trustedCatalog); container = new CompositionContainer(catalog, isThreadSafe: true); serviceLocator = new DelegateServiceLocator(new ExportProviderServiceLocator(container)); } var modules = serviceLocator.GetAllInstances <IAppServerModule>().AsArray(); if (modules.Length == 1) { CompositionHelper.ComposeExportedValueEx(container, modules[0]); } else { foreach (var m in modules) { CompositionHelper.ComposeExportedValue(container, m, m.GetType()); } } modules.ForAll(ctx2 => { var m = ctx2.Item; if (m.IsInitialized) { // no need to initialize return; } //TODO: add implementation(s) var logger = new AggregateLogger(); var moduleRootDir = new DirectoryInfo(Path.Combine(ctx2.State.ModuleDirectory, m.Name)).CreateDirectoryDeep(); var moduleCtx = new SimpleAppServerModuleContext(m); moduleCtx.Config = new IniFileConfigRepository(Path.Combine(moduleRootDir.FullName, "config.ini")); moduleCtx.InnerServiceLocator = ctx2.State.ServiceLocator; moduleCtx.Logger = logger; moduleCtx.OtherModules = ctx2.State.AllModules .Where(CreateWherePredicateForExtractingOtherModules(m)); moduleCtx.SetAssemblyFile(ctx2.State.AssemblyFile.FullName); var moduleInitCtx = new SimpleAppServerModuleInitContext(); moduleInitCtx.ModuleContext = moduleCtx; moduleInitCtx.RootDirectory = moduleRootDir.FullName; m.Initialize(moduleInitCtx); ctx2.State .NewModules .Add(m); }, actionState: new { AllModules = modules, AssemblyFile = f, ModuleDirectory = ctx.State.ModuleDirectory, NewModules = ctx.State.NewModules, ServiceLocator = serviceLocator, }, throwExceptions: true); }, actionState: new { CompositionCatalog = this.TrustedCompositionCatalog .Clone(cloneCatalogData: false), Logger = this.Logger, ModuleDirectory = modDir.FullName, NewModules = newModules, }, throwExceptions: false); if (ex != null) { this.Logger .Log(msg: ex, tag: LOG_TAG_PREFIX + "LoadModules", categories: LoggerFacadeCategories.Errors); } } this.Modules = newModules.Where(m => m.IsInitialized) .ToArray(); if (this.Modules.Length > 0) { this.Logger .Log(msg: string.Format("{0} modules were loaded.", this.Modules.Length), tag: LOG_TAG_PREFIX + "LoadModules", categories: LoggerFacadeCategories.Information); } else { this.Logger .Log(msg: "No module was loaded.", tag: LOG_TAG_PREFIX + "LoadModules", categories: LoggerFacadeCategories.Warnings); } this.RefreshEntityAssemblyList(); ex = newModules.Where(m => m.CanStart && m.IsInitialized) .ForAllAsync(ctx => { var m = ctx.Item; m.Start(); }, throwExceptions: false); if (ex != null) { this.Logger .Log(msg: ex, tag: LOG_TAG_PREFIX + "StartModules", categories: LoggerFacadeCategories.Errors); } }