/// <inheritdoc/> public bool Execute(SanteDBConfiguration configuration) { this.m_backup = configuration.GetSection <ApplicationServiceContextConfigurationSection>(); // Get the configuration var config = this.Feature.Configuration as GenericFeatureConfiguration; if (config != null) { var sp = configuration.GetSection <ApplicationServiceContextConfigurationSection>().ServiceProviders; var types = AppDomain.CurrentDomain.GetAllTypes(); var appConfig = configuration.GetSection <ApplicationServiceContextConfigurationSection>(); // Map configuration over to the features section foreach (var pvd in types.Where(t => t.IsInterface && typeof(IServiceImplementation).IsAssignableFrom(t)).ToArray()) { object value = null; if (config.Values.TryGetValue(pvd.Name, out value) && value != null && !sp.Any(t => value as Type == t.Type)) { appConfig.ServiceProviders.Add(new TypeReferenceConfiguration(value as Type)); } } //// Remove any sp which aren't configured for any service impl //sp.RemoveAll(r => !config.Values.Any(v => v.Value == r.Type) && !typeof(IDaemonService).IsAssignableFrom(r.Type) && // typeof(IServiceImplementation).IsAssignableFrom(r.Type)); } return(true); }
/// <summary> /// Add service /// </summary> public void AddServiceProvider(Type serviceType, bool addToConfiguration) { this.m_tracer.TraceInfo("Adding service provider {0}", serviceType.FullName); this.m_serviceManager.AddServiceProvider(serviceType); ApplicationServiceContextConfigurationSection appSection = this.Configuration.GetSection <ApplicationServiceContextConfigurationSection>(); if (addToConfiguration && !appSection.ServiceProviders.Any(o => o.Type == serviceType)) { appSection.ServiceProviders.Add(new TypeReferenceConfiguration(serviceType)); } }
/// <summary> /// Remove a service provider /// </summary> public void RemoveServiceProvider(Type serviceType, bool updateConfiguration) { if (serviceType == null) { throw new ArgumentNullException(nameof(serviceType)); } ApplicationServiceContextConfigurationSection appSection = this.Configuration.GetSection <ApplicationServiceContextConfigurationSection>(); this.m_serviceManager.RemoveServiceProvider(serviceType); if (updateConfiguration) { appSection.ServiceProviders.RemoveAll(t => t.Type == serviceType); } }
/// <summary> /// Get all types from core classes of entity and act and create shims in the model serialization binder /// </summary> public RemoteRepositoryFactory(IConfigurationManager configurationManager, IServiceManager serviceManager, ILocalizationService localizationService) { foreach (var t in typeof(Entity).Assembly.ExportedTypes.Where(o => typeof(Entity).IsAssignableFrom(o))) { ModelSerializationBinder.RegisterModelType(typeof(EntityMaster <>).MakeGenericType(t)); } foreach (var t in typeof(Act).Assembly.ExportedTypes.Where(o => typeof(Act).IsAssignableFrom(o))) { ModelSerializationBinder.RegisterModelType(typeof(ActMaster <>).MakeGenericType(t)); } ModelSerializationBinder.RegisterModelType(typeof(EntityRelationshipMaster)); this.m_localizationService = localizationService; this.m_serviceManager = serviceManager; this.m_configuration = configurationManager.GetSection <ApplicationServiceContextConfigurationSection>(); }
/// <summary> /// Adds a singleton /// </summary> public void AddServiceProvider(object serviceInstance) { lock (this.m_lock) { if (serviceInstance is IConfigurationManager cmgr && this.m_configuration == null) { this.m_configuration = cmgr.GetSection <ApplicationServiceContextConfigurationSection>(); } this.ValidateServiceSignature(serviceInstance.GetType()); this.m_serviceRegistrations.Add(new ServiceInstanceInformation(serviceInstance, this)); this.m_notConfiguredServices.Clear(); if (serviceInstance is IServiceFactory sf) { this.AddServiceFactory(sf); } } }
/// <summary> /// Start the process /// </summary> public bool Start() { if (!this.IsRunning) { Stopwatch startWatch = new Stopwatch(); try { if (this.GetService <IConfigurationManager>() == null) { throw new InvalidOperationException("Cannot find configuration manager!"); } if (this.m_configuration == null) { this.m_configuration = this.GetService <IConfigurationManager>().GetSection <ApplicationServiceContextConfigurationSection>(); } // Add configured services foreach (var svc in this.m_configuration.ServiceProviders) { if (svc.Type == null) { this.m_tracer.TraceWarning("Cannot find service {0}, skipping", svc.TypeXml); } else if (this.m_serviceRegistrations.Any(p => p.ServiceImplementer == svc.Type)) { this.m_tracer.TraceWarning("Duplicate registration of type {0}, skipping", svc.TypeXml); } else { if (svc.Type == null) { this.m_tracer.TraceWarning("Cannot find service {0}, skipping", svc.TypeXml); } else if (this.m_serviceRegistrations.Any(p => p.ServiceImplementer == svc.Type)) { this.m_tracer.TraceWarning("Duplicate registration of type {0}, skipping", svc.TypeXml); } else { this.AddServiceProvider(svc.Type); } } } using (AuthenticationContext.EnterSystemContext()) { this.Starting?.Invoke(this, EventArgs.Empty); startWatch.Start(); this.m_tracer.TraceInfo("Loading singleton services"); foreach (var svc in this.m_serviceRegistrations.ToArray().Where(o => o.InstantiationType == ServiceInstantiationType.Singleton)) { this.m_tracer.TraceInfo("Instantiating {0}...", svc.ServiceImplementer.FullName); svc.GetInstance(); } this.m_tracer.TraceInfo("Starting Daemon services"); foreach (var dc in this.m_serviceRegistrations.ToArray().Where(o => o.ImplementedServices.Contains(typeof(IDaemonService))).Select(o => o.GetInstance() as IDaemonService)) { if (dc == null) { continue; } this.m_tracer.TraceInfo("Starting daemon {0}...", dc.ServiceName); if (dc != this && !dc.Start()) { throw new Exception($"Service {dc} reported unsuccessful start"); } } if (this.Started != null) { this.Started(this, null); } } } finally { startWatch.Stop(); } this.m_tracer.TraceInfo("Startup completed successfully in {0} ms...", startWatch.ElapsedMilliseconds); this.Started?.Invoke(this, EventArgs.Empty); this.IsRunning = true; } return(this.IsRunning); }
/// <summary> /// The main entry point for the application. /// </summary> static void Main(String[] args) { // Trace copyright information Assembly entryAsm = Assembly.GetEntryAssembly(); // Dump some info Trace.TraceInformation("SanteDB Startup : v{0}", entryAsm.GetName().Version); Trace.TraceInformation("SanteDB Working Directory : {0}", entryAsm.Location); Trace.TraceInformation("Operating System: {0} {1}", Environment.OSVersion.Platform, Environment.OSVersion.VersionString); Trace.TraceInformation("CLI Version: {0}", Environment.Version); AppDomain.CurrentDomain.SetData( "DataDirectory", Path.GetDirectoryName(typeof(Program).Assembly.Location)); // Handle Unahndled exception AppDomain.CurrentDomain.UnhandledException += (o, e) => { Trace.TraceError("++++++ FATAL APPLICATION ERROR ++++++++\r\n{0}", e.ExceptionObject); EventLog.WriteEntry("SanteDB Host Process", $"++++++ FATAL APPLICATION ERROR ++++++++\r\n{e.ExceptionObject}", EventLogEntryType.Error, 999); Environment.Exit(999); }; // Parser ParameterParser <ConsoleParameters> parser = new ParameterParser <ConsoleParameters>(); bool hasConsole = true; try { var parameters = parser.Parse(args); EntitySource.Current = new EntitySource(new PersistenceEntitySource()); // What to do? if (parameters.ShowHelp) { parser.WriteHelp(Console.Out); } else if (parameters.Install) { if (!ServiceTools.ServiceInstaller.ServiceIsInstalled("SanteDB")) { Console.WriteLine("Installing Service..."); ServiceTools.ServiceInstaller.Install("SanteDB", "SanteDB Host Process", Assembly.GetEntryAssembly().Location, null, null, ServiceTools.ServiceBootFlag.AutoStart); } } else if (parameters.UnInstall) { if (ServiceTools.ServiceInstaller.ServiceIsInstalled("SanteDB")) { Console.WriteLine("Un-Installing Service..."); ServiceTools.ServiceInstaller.StopService("SanteDB"); ServiceTools.ServiceInstaller.Uninstall("SanteDB"); } } else if (parameters.GenConfig) { SanteDBConfiguration configuration = new SanteDBConfiguration(); ApplicationServiceContextConfigurationSection serverConfiguration = new ApplicationServiceContextConfigurationSection(); Console.WriteLine("Will generate full default configuration..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(typeof(Program).Assembly.Location), "*.dll")) { try { var asm = Assembly.LoadFile(file); Console.WriteLine("Adding service providers from {0}...", file); serverConfiguration.ServiceProviders.AddRange(asm.ExportedTypes.Where(t => typeof(IServiceImplementation).IsAssignableFrom(t) && !t.IsAbstract && !t.ContainsGenericParameters && t.GetCustomAttribute <ServiceProviderAttribute>() != null).Select(o => new TypeReferenceConfiguration(o))); Console.WriteLine("Adding sections from {0}...", file); configuration.Sections.AddRange(asm.ExportedTypes.Where(t => typeof(IConfigurationSection).IsAssignableFrom(t)).Select(t => CreateFullXmlObject(t))); } catch (Exception e) { Console.WriteLine("Skipping {0} due to {1}", file, e.Message); } } configuration.RemoveSection <ApplicationServiceContextConfigurationSection>(); serverConfiguration.ThreadPoolSize = Environment.ProcessorCount; configuration.AddSection(serverConfiguration); using (var fs = File.Create(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "default.config.xml"))) configuration.Save(fs); } else if (parameters.ConsoleMode) { Console.WriteLine("SanteDB (SanteDB) {0} ({1})", entryAsm.GetName().Version, entryAsm.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion); Console.WriteLine("{0}", entryAsm.GetCustomAttribute <AssemblyCopyrightAttribute>().Copyright); Console.WriteLine("Complete Copyright information available at http://SanteDB.codeplex.com/wikipage?title=Contributions"); ServiceUtil.Start(typeof(Program).GUID); if (!parameters.StartupTest) { // Did the service start properly? if (!ApplicationContext.Current.IsRunning) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Application context did not start properly and is in maintenance mode..."); Console.ResetColor(); } ManualResetEvent quitEvent = new ManualResetEvent(false); Console.CancelKeyPress += (o, e) => { Console.WriteLine("Service shutting down..."); ServiceUtil.Stop(); quitEvent.Set(); }; Console.WriteLine("Service started (CTRL+C to stop)..."); quitEvent.WaitOne(); } } else { hasConsole = false; ServiceBase[] servicesToRun = new ServiceBase[] { new SanteDB() }; ServiceBase.Run(servicesToRun); } } catch (Exception e) { #if DEBUG Trace.TraceError("011 899 981 199 911 9725 3!!! {0}", e.ToString()); if (hasConsole) { Console.WriteLine("011 899 981 199 911 9725 3!!! {0}", e.ToString()); } EventLog.WriteEntry("SanteDB Host Process", $"011 899 981 199 911 9725 3!!! {e}", EventLogEntryType.Error, 911); #else Trace.TraceError("Error encountered: {0}. Will terminate", e.Message); #endif Environment.Exit(911); } }
/// <summary> /// Get a bare bones configuration /// </summary> public SanteDBConfiguration GetDefaultConfiguration() { // TODO: Bring up initial settings dialog and utility var retVal = new SanteDBConfiguration(); // Initial Applet configuration AppletConfigurationSection appletSection = new AppletConfigurationSection() { AppletDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SanteDB", this.m_instanceName, "applets"), StartupAsset = "org.santedb.uicore", Security = new AppletSecurityConfiguration() { AllowUnsignedApplets = true, TrustedPublishers = new List <string>() { "82C63E1E9B87578D0727E871D7613F2F0FAF683B", "4326A4421216AC254DA93DC61B93160B08925BB1" } } }; // Initial applet style ApplicationConfigurationSection appSection = new ApplicationConfigurationSection() { Style = StyleSchemeType.Dark, UserPrefDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SanteDB", this.m_instanceName, "userpref"), Cache = new CacheConfiguration() { MaxAge = new TimeSpan(0, 5, 0).Ticks, MaxSize = 1000, MaxDirtyAge = new TimeSpan(0, 20, 0).Ticks, MaxPressureAge = new TimeSpan(0, 2, 0).Ticks } }; // App service var appServiceSection = new ApplicationServiceContextConfigurationSection() { ThreadPoolSize = Environment.ProcessorCount * 16, ServiceProviders = new List <TypeReferenceConfiguration>() { new TypeReferenceConfiguration(typeof(AesSymmetricCrypographicProvider)), new TypeReferenceConfiguration(typeof(MemoryTickleService)), new TypeReferenceConfiguration(typeof(SHA256PasswordHasher)), new TypeReferenceConfiguration(typeof(SanteDB.Core.Security.DefaultPolicyDecisionService)), new TypeReferenceConfiguration(typeof(DataPolicyFilterService)), new TypeReferenceConfiguration(typeof(NetworkInformationService)), new TypeReferenceConfiguration(typeof(BusinessRulesDaemonService)), new TypeReferenceConfiguration(typeof(AgsService)), new TypeReferenceConfiguration(typeof(SanteDB.Caching.Memory.MemoryCacheService)), new TypeReferenceConfiguration(typeof(SanteDB.Caching.Memory.MemoryAdhocCacheService)), new TypeReferenceConfiguration(typeof(DefaultThreadPoolService)), new TypeReferenceConfiguration(typeof(SimpleCarePlanService)), new TypeReferenceConfiguration(typeof(MemorySessionManagerService)), new TypeReferenceConfiguration(typeof(AmiUpdateManager)), new TypeReferenceConfiguration(typeof(AppletClinicalProtocolRepository)), new TypeReferenceConfiguration(typeof(AppletLocalizationService)), new TypeReferenceConfiguration(typeof(MemoryQueryPersistenceService)), new TypeReferenceConfiguration(typeof(AuditDaemonService)), new TypeReferenceConfiguration(typeof(SimpleQueueFileProvider)), new TypeReferenceConfiguration(typeof(SimplePatchService)), new TypeReferenceConfiguration(typeof(DefaultBackupService)), new TypeReferenceConfiguration(typeof(DcAppletManagerService)), new TypeReferenceConfiguration(typeof(AppletBiRepository)), new TypeReferenceConfiguration(typeof(DefaultOperatingSystemInfoService)), new TypeReferenceConfiguration(typeof(AppletSubscriptionRepository)), new TypeReferenceConfiguration(typeof(AmiSecurityChallengeProvider)), new TypeReferenceConfiguration(typeof(InMemoryPivotProvider)), new TypeReferenceConfiguration(typeof(DefaultDataSigningService)), new TypeReferenceConfiguration(typeof(GenericConfigurationPushService)), new TypeReferenceConfiguration(typeof(QrBarcodeGenerator)), new TypeReferenceConfiguration(typeof(FileSystemDispatcherQueueService)) } }; // Security configuration SecurityConfigurationSection secSection = new SecurityConfigurationSection() { DeviceName = Environment.MachineName, AuditRetention = new TimeSpan(30, 0, 0, 0, 0), DomainAuthentication = DomainClientAuthentication.Inline }; // Device key //var certificate = X509CertificateUtils.FindCertificate(X509FindType.FindBySubjectName, StoreLocation.LocalMachine, StoreName.My, String.Format("DN={0}.mobile.santedb.org", macAddress)); //secSection.DeviceSecret = certificate?.Thumbprint; // Rest Client Configuration ServiceClientConfigurationSection serviceSection = new ServiceClientConfigurationSection() { RestClientType = typeof(RestClient) }; // Trace writer #if DEBUG DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection() { TraceWriter = new System.Collections.Generic.List <TraceWriterConfiguration>() { new TraceWriterConfiguration() { Filter = System.Diagnostics.Tracing.EventLevel.Informational, InitializationData = "SanteDB", TraceWriter = typeof(LogTraceWriter) }, new TraceWriterConfiguration() { Filter = System.Diagnostics.Tracing.EventLevel.Informational, InitializationData = "SanteDB", TraceWriter = typeof(FileTraceWriter) } } }; #else DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection() { TraceWriter = new List <TraceWriterConfiguration>() { new TraceWriterConfiguration() { Filter = System.Diagnostics.Tracing.EventLevel.Warning, InitializationData = "SanteDB", TraceWriter = typeof(FileTraceWriter) } } }; #endif retVal.Sections.Add(new FileSystemDispatcherQueueConfigurationSection() { QueuePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SanteDB", this.m_instanceName, "queue"), }); retVal.Sections.Add(appServiceSection); retVal.Sections.Add(appletSection); retVal.Sections.Add(diagSection); retVal.Sections.Add(appSection); retVal.Sections.Add(secSection); retVal.Sections.Add(serviceSection); retVal.Sections.Add(new AuditAccountabilityConfigurationSection() { AuditFilters = new List <AuditFilterConfiguration>() { // Audit any failure - No matter which event new AuditFilterConfiguration(null, null, SanteDB.Core.Auditing.OutcomeIndicator.EpicFail | SanteDB.Core.Auditing.OutcomeIndicator.MinorFail | SanteDB.Core.Auditing.OutcomeIndicator.SeriousFail, true, true), // Audit anything that creates, reads, or updates data new AuditFilterConfiguration(SanteDB.Core.Auditing.ActionType.Create | SanteDB.Core.Auditing.ActionType.Read | SanteDB.Core.Auditing.ActionType.Update | SanteDB.Core.Auditing.ActionType.Delete, null, null, true, true) } }); retVal.Sections.Add(new DcDataConfigurationSection() { MainDataSourceConnectionStringName = "santeDbData", MessageQueueConnectionStringName = "santeDbQueue" }); retVal.AddSection(AgsService.GetDefaultConfiguration()); retVal.Sections.Add(new SynchronizationConfigurationSection() { PollInterval = new TimeSpan(0, 5, 0), ForbiddenResouces = new List <SynchronizationForbidConfiguration>() { new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "DeviceEntity"), new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "ApplicationEntity"), new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "Concept"), new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "ConceptSet"), new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "Place"), new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "ReferenceTerm"), new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "AssigningAuthority"), new SynchronizationForbidConfiguration(SynchronizationOperationType.Obsolete, "UserEntity") } }); foreach (var t in AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.IsDynamic) .SelectMany(a => { try { return(a.ExportedTypes); } catch (Exception) { return(Type.EmptyTypes); } }) .Where(t => typeof(IInitialConfigurationProvider).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface)) { retVal = (Activator.CreateInstance(t) as IInitialConfigurationProvider).Provide(retVal); } return(retVal); }
/// <summary> /// The main entry point for the application. /// </summary> private static void Main(String[] args) { // Trace copyright information Assembly entryAsm = Assembly.GetEntryAssembly(); // Dump some info Trace.TraceInformation("SanteDB Startup : v{0}", entryAsm.GetName().Version); Trace.TraceInformation("SanteDB Working Directory : {0}", entryAsm.Location); Trace.TraceInformation("Operating System: {0} {1}", Environment.OSVersion.Platform, Environment.OSVersion.VersionString); Trace.TraceInformation("CLI Version: {0}", Environment.Version); AppDomain.CurrentDomain.SetData( "DataDirectory", Path.GetDirectoryName(typeof(Program).Assembly.Location)); // Handle Unahndled exception AppDomain.CurrentDomain.UnhandledException += (o, e) => { Trace.TraceError("++++++ FATAL APPLICATION ERROR ++++++++\r\n{0}", e.ExceptionObject); EventLog.WriteEntry("SanteDB Host Process", $"++++++ FATAL APPLICATION ERROR ++++++++\r\n{e.ExceptionObject}", EventLogEntryType.Error, 999); Environment.Exit(999); }; // Parser ParameterParser <ConsoleParameters> parser = new ParameterParser <ConsoleParameters>(); bool hasConsole = true; try { var parameters = parser.Parse(args); var instanceSuffix = !String.IsNullOrEmpty(parameters.InstanceName) ? $"-{parameters.InstanceName}" : null; // What to do? if (parameters.ShowHelp) { parser.WriteHelp(Console.Out); } else if (parameters.InstallCerts) { Console.WriteLine("Installing security certificates..."); SecurityExtensions.InstallCertsForChain(); } else if (parameters.Install) { if (!ServiceTools.ServiceInstaller.ServiceIsInstalled($"SanteDB{instanceSuffix}")) { Console.WriteLine("Installing Service..."); if (!String.IsNullOrEmpty(instanceSuffix)) { var configFile = parameters.ConfigFile; if (String.IsNullOrEmpty(configFile)) { configFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), $"santedb.config.{parameters.InstanceName}.xml"); } else if (!Path.IsPathRooted(configFile)) { configFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), configFile); } ServiceTools.ServiceInstaller.Install($"SanteDB{instanceSuffix}", $"SanteDB Host Process - {parameters.InstanceName}", $"{Assembly.GetEntryAssembly().Location} --name={parameters.InstanceName} --config={configFile}", null, null, ServiceTools.ServiceBootFlag.AutoStart); } else { ServiceTools.ServiceInstaller.Install($"SanteDB", "SanteDB Host Process", $"{Assembly.GetEntryAssembly().Location}", null, null, ServiceTools.ServiceBootFlag.AutoStart); } } } else if (parameters.UnInstall) { if (ServiceTools.ServiceInstaller.ServiceIsInstalled($"SanteDB{instanceSuffix}")) { Console.WriteLine("Un-Installing Service..."); ServiceTools.ServiceInstaller.StopService($"SanteDB{instanceSuffix}"); ServiceTools.ServiceInstaller.Uninstall($"SanteDB{instanceSuffix}"); } } else if (parameters.GenConfig) { SanteDBConfiguration configuration = new SanteDBConfiguration(); ApplicationServiceContextConfigurationSection serverConfiguration = new ApplicationServiceContextConfigurationSection(); Console.WriteLine("Will generate full default configuration..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(typeof(Program).Assembly.Location), "*.dll")) { try { var asm = Assembly.LoadFile(file); Console.WriteLine("Adding service providers from {0}...", file); serverConfiguration.ServiceProviders.AddRange(asm.ExportedTypes.Where(t => typeof(IServiceImplementation).IsAssignableFrom(t) && !t.IsAbstract && !t.ContainsGenericParameters && t.GetCustomAttribute <ServiceProviderAttribute>() != null).Select(o => new TypeReferenceConfiguration(o))); Console.WriteLine("Adding sections from {0}...", file); configuration.Sections.AddRange(asm.ExportedTypes.Where(t => typeof(IConfigurationSection).IsAssignableFrom(t)).Select(t => CreateFullXmlObject(t))); } catch (Exception e) { Console.WriteLine("Skipping {0} due to {1}", file, e.Message); } } configuration.RemoveSection <ApplicationServiceContextConfigurationSection>(); serverConfiguration.ThreadPoolSize = Environment.ProcessorCount * 16; configuration.AddSection(serverConfiguration); using (var fs = File.Create(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "default.config.xml"))) configuration.Save(fs); } else if (parameters.ConsoleMode) { Console.WriteLine("SanteDB (SanteDB) {0} ({1})", entryAsm.GetName().Version, entryAsm.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion); Console.WriteLine("{0}", entryAsm.GetCustomAttribute <AssemblyCopyrightAttribute>().Copyright); Console.WriteLine("Complete Copyright information available at http://SanteDB.codeplex.com/wikipage?title=Contributions"); ServiceUtil.Start(typeof(Program).GUID, new FileConfigurationService(parameters.ConfigFile)); if (!parameters.StartupTest) { // Did the service start properly? if (!ApplicationServiceContext.Current.IsRunning) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Application context did not start properly and is in maintenance mode..."); Console.ResetColor(); } if (Environment.OSVersion.Platform == PlatformID.Win32NT) { ManualResetEvent quitEvent = new ManualResetEvent(false); Console.CancelKeyPress += (o, e) => { Console.WriteLine("Service shutting down..."); ServiceUtil.Stop(); quitEvent.Set(); }; Console.WriteLine("Service started (CTRL+C to stop)..."); quitEvent.WaitOne(); } else { // Now wait until the service is exiting va SIGTERM or SIGSTOP UnixSignal[] signals = new UnixSignal[] { new UnixSignal(Mono.Unix.Native.Signum.SIGINT), new UnixSignal(Mono.Unix.Native.Signum.SIGTERM), new UnixSignal(Mono.Unix.Native.Signum.SIGQUIT), new UnixSignal(Mono.Unix.Native.Signum.SIGHUP) }; int signal = UnixSignal.WaitAny(signals); // Gracefully shutdown ServiceUtil.Stop(); try // remove the lock file { File.Delete("/tmp/SanteDB.exe.lock"); } catch { } } } } else { hasConsole = false; ServiceBase[] servicesToRun = new ServiceBase[] { new SanteDBService() }; ServiceBase.Run(servicesToRun); } } catch (Exception e) { #if DEBUG Trace.TraceError("011 899 981 199 911 9725 3!!! {0}", e.ToString()); EventLog.WriteEntry("SanteDB Host Process", $"011 899 981 199 911 9725 3!!! {e}", EventLogEntryType.Error, 911); #else Trace.TraceError("Error encountered: {0}. Will terminate", e); #endif if (hasConsole) { Console.WriteLine("011 899 981 199 911 9725 3!!! {0}", e.ToString()); } try { EventLog.WriteEntry("SanteDB Host Process", $"011 899 981 199 911 9725 3!!! {e}", EventLogEntryType.Error, 911); } catch (Exception e1) { Trace.TraceWarning("Could not emit the error to the EventLog - {0}", e1); } Environment.Exit(911); } }
/// <summary> /// Load the configuration file /// </summary> public SanteDBConfiguration Load() { if (!String.IsNullOrEmpty(this.m_configPath)) { using (var fs = File.OpenRead(this.m_configPath)) { return(SanteDBConfiguration.Load(fs)); } } else { var retVal = new SanteDBConfiguration(); // Inital data source DcDataConfigurationSection dataSection = new DcDataConfigurationSection() { MainDataSourceConnectionStringName = "santeDbData", MessageQueueConnectionStringName = "santeDbData", MailDataStore = "santeDbData", ConnectionString = new System.Collections.Generic.List <ConnectionString>() { new ConnectionString() { Name = "santeDbData", Value = $"dbfile={(String.IsNullOrEmpty(this.m_dataPath) ? "SanteDB.debug.sqlite" : this.m_dataPath )}", Provider = "sqlite" } } }; JavascriptRulesConfigurationSection jsConfiguration = new JavascriptRulesConfigurationSection() { DebugMode = true, WorkerInstances = 1 }; // Initial Applet configuration AppletConfigurationSection appletSection = new AppletConfigurationSection() { Security = new AppletSecurityConfiguration() { AllowUnsignedApplets = true, TrustedPublishers = new List <string>() { "82C63E1E9B87578D0727E871D7613F2F0FAF683B" } } }; // Initial applet style ApplicationConfigurationSection appSection = new ApplicationConfigurationSection() { Style = StyleSchemeType.Dark, UserPrefDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SdbDebug", "userpref"), Cache = new CacheConfiguration() { MaxAge = new TimeSpan(0, 5, 0).Ticks, MaxSize = 1000, MaxDirtyAge = new TimeSpan(0, 20, 0).Ticks, MaxPressureAge = new TimeSpan(0, 2, 0).Ticks } }; // Application service section ApplicationServiceContextConfigurationSection appServiceSection = new ApplicationServiceContextConfigurationSection() { ThreadPoolSize = Environment.ProcessorCount, ServiceProviders = new List <TypeReferenceConfiguration>() { new TypeReferenceConfiguration(typeof(SanteDB.Core.Security.DefaultPolicyDecisionService)), new TypeReferenceConfiguration(typeof(SQLitePolicyInformationService)), new TypeReferenceConfiguration(typeof(LocalRepositoryFactoryService)), //typeof(LocalAlertService).AssemblyQualifiedName, new TypeReferenceConfiguration(typeof(LocalTagPersistenceService)), new TypeReferenceConfiguration(typeof(NetworkInformationService)), new TypeReferenceConfiguration(typeof(BusinessRulesDaemonService)), new TypeReferenceConfiguration(typeof(PersistenceEntitySource)), new TypeReferenceConfiguration(typeof(SanteDB.Caching.Memory.MemoryCacheService)), new TypeReferenceConfiguration(typeof(SanteDB.Core.Services.Impl.DefaultThreadPoolService)), new TypeReferenceConfiguration(typeof(MemorySessionManagerService)), new TypeReferenceConfiguration(typeof(AmiUpdateManager)), new TypeReferenceConfiguration(typeof(AppletClinicalProtocolRepository)), new TypeReferenceConfiguration(typeof(MemoryQueryPersistenceService)), new TypeReferenceConfiguration(typeof(SimpleQueueFileProvider)), new TypeReferenceConfiguration(typeof(SimpleCarePlanService)), new TypeReferenceConfiguration(typeof(SimplePatchService)), new TypeReferenceConfiguration(typeof(DebugAppletManagerService)), new TypeReferenceConfiguration(typeof(SQLiteConnectionManager)), new TypeReferenceConfiguration(typeof(SQLitePersistenceService)), new TypeReferenceConfiguration(typeof(SQLite.Net.Platform.SqlCipher.SQLitePlatformSqlCipher)) } }; // Security configuration SecurityConfigurationSection secSection = new SecurityConfigurationSection() { DeviceName = Environment.MachineName, AuditRetention = new TimeSpan(30, 0, 0, 0, 0) }; // Device key //var certificate = X509CertificateUtils.FindCertificate(X509FindType.FindBySubjectName, StoreLocation.LocalMachine, StoreName.My, String.Format("DN={0}.mobile.santedb.org", macAddress)); //secSection.DeviceSecret = certificate?.Thumbprint; // Rest Client Configuration ServiceClientConfigurationSection serviceSection = new ServiceClientConfigurationSection() { RestClientType = typeof(RestClient) }; // Trace writer DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection() { TraceWriter = new System.Collections.Generic.List <TraceWriterConfiguration>() { new TraceWriterConfiguration() { Filter = System.Diagnostics.Tracing.EventLevel.Error, InitializationData = "SanteDB", TraceWriter = typeof(ConsoleTraceWriter) }, new TraceWriterConfiguration() { Filter = System.Diagnostics.Tracing.EventLevel.LogAlways, InitializationData = "SanteDB", TraceWriter = typeof(FileTraceWriter) } } }; retVal.Sections.Add(appServiceSection); retVal.Sections.Add(appletSection); retVal.Sections.Add(dataSection); retVal.Sections.Add(diagSection); retVal.Sections.Add(appSection); retVal.Sections.Add(secSection); retVal.Sections.Add(serviceSection); retVal.Sections.Add(jsConfiguration); retVal.Sections.Add(new SynchronizationConfigurationSection() { PollInterval = new TimeSpan(0, 5, 0) }); return(retVal); } }
/// <summary> /// Start the application context /// </summary> public bool Start() { if (!this.m_running) { Stopwatch startWatch = new Stopwatch(); try { startWatch.Start(); if (this.Starting != null) { this.Starting(this, null); } // If there is no configuration manager then add the local Trace.TraceInformation("STAGE0 START: Load Configuration"); if (this.GetService <IConfigurationManager>() == null) { throw new InvalidOperationException("Cannot find configuration manager!"); } this.m_configuration = this.GetService <IConfigurationManager>().GetSection <ApplicationServiceContextConfigurationSection>(); if (this.m_configuration == null) { throw new InvalidOperationException("Cannot load configuration, perhaps the services aren't installed?"); } // Assign diagnostics var config = this.GetService <IConfigurationManager>().GetSection <DiagnosticsConfigurationSection>(); if (config != null) { foreach (var writer in config.TraceWriter) { Tracer.AddWriter(Activator.CreateInstance(writer.TraceWriter, writer.Filter, writer.InitializationData) as TraceWriter, writer.Filter); } } #if DEBUG else { Tracer.AddWriter(new SystemDiagnosticsTraceWriter(), System.Diagnostics.Tracing.EventLevel.LogAlways); } #endif // Add this this.m_serviceInstances.Add(this); Trace.TraceInformation("STAGE1 START: Loading services"); foreach (var svc in this.m_configuration.ServiceProviders) { if (svc.Type == null) { Trace.TraceWarning("Cannot find service {0}, skipping", svc.TypeXml); } else { Trace.TraceInformation("Creating {0}...", svc.Type); var instance = Activator.CreateInstance(svc.Type); this.m_serviceInstances.Add(instance); } } Trace.TraceInformation("STAGE2 START: Starting Daemons"); foreach (var dc in this.m_serviceInstances.OfType <IDaemonService>().ToArray()) { if (!dc.Start()) { throw new Exception($"Service {dc} reported unsuccessful start"); } } Trace.TraceInformation("STAGE3 START: Notify ApplicationContext has started"); if (this.Started != null) { this.Started(this, null); } this.StartTime = DateTime.Now; AuditUtil.AuditApplicationStartStop(EventTypeCodes.ApplicationStart); } finally { startWatch.Stop(); } Trace.TraceInformation("SanteDB startup completed successfully in {0} ms...", startWatch.ElapsedMilliseconds); this.m_running = true; } return(true); }