Exemple #1
0
            /// <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);
            }
Exemple #2
0
        /// <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));
            }
        }
Exemple #3
0
        /// <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);
            }
        }
Exemple #4
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #9
0
        /// <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);
            }
        }
Exemple #11
0
        /// <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);
        }