/// <summary>
        /// Start the application context
        /// </summary>
        public static bool Start(ConsoleParameters consoleParms)
        {
            var retVal = new MiniApplicationContext(consoleParms.InstanceName);

            // Not configured
            if (!retVal.ConfigurationPersister.IsConfigured)
            {
                return(false);
            }
            else
            { // load configuration
                try
                {
                    // Set master application context
                    ApplicationServiceContext.Current = ApplicationContext.Current = retVal;
                    retVal.ConfigurationPersister.Backup(retVal.Configuration);

                    retVal.GetService <IServiceManager>().AddServiceProvider(typeof(DefaultBackupService));
                    retVal.GetService <IBackupService>().AutoRestore();

                    retVal.m_tracer = Tracer.GetTracer(typeof(MiniApplicationContext));
                    var configuration = retVal.Configuration.GetSection <DiagnosticsConfigurationSection>();
                    foreach (var tr in configuration.TraceWriter)
                    {
                        Tracer.AddWriter(Activator.CreateInstance(tr.TraceWriter, tr.Filter, tr.InitializationData, configuration.Sources.ToDictionary(o => o.SourceName, o => o.Filter)) as TraceWriter, tr.Filter);
                    }
                    var appService = retVal.GetService <IAppletManagerService>();

                    retVal.SetProgress("Loading configuration", 0.2f);

                    if (consoleParms.References != null)
                    {
                        MiniApplicationContext.LoadReferences(retVal, consoleParms.References);
                    }

                    // Does openiz.js exist as an asset?
                    var oizJs = appService.Applets.ResolveAsset("/org.santedb.core/js/santedb.js");

                    // Load all solution manifests and attempt to find their pathspec
                    if (!String.IsNullOrEmpty(consoleParms.SolutionFile))
                    {
                        LoadSolution(consoleParms.SolutionFile, appService);
                    }


                    // Load all user-downloaded applets in the data directory
                    if (consoleParms.AppletDirectories != null)
                    {
                        LoadApplets(consoleParms.AppletDirectories.OfType <String>(), appService);
                    }


                    if (oizJs?.Content != null)
                    {
                        byte[] content  = appService.Applets.RenderAssetContent(oizJs);
                        var    oizJsStr = Encoding.UTF8.GetString(content, 0, content.Length);
                        oizJs.Content = oizJsStr + (appService as MiniAppletManagerService).GetShimMethods();
                    }

                    // Set the entity source
                    EntitySource.Current = new EntitySource(retVal.GetService <IEntitySourceProvider>());

                    // Ensure data migration exists
                    var hasDatabase = retVal.ConfigurationManager.Configuration.GetSection <DcDataConfigurationSection>().ConnectionString.Count > 0;
                    try
                    {
                        // If the DB File doesn't exist we have to clear the migrations
                        if (hasDatabase && !File.Exists(retVal.ConfigurationManager.GetConnectionString(retVal.Configuration.GetSection <DcDataConfigurationSection>().MainDataSourceConnectionStringName).GetComponent("dbfile")))
                        {
                            retVal.m_tracer.TraceWarning("Can't find the SanteDB database, will re-install all migrations");
                            retVal.Configuration.GetSection <DcDataConfigurationSection>().MigrationLog.Entry.Clear();
                        }
                        retVal.SetProgress("Migrating databases", 0.6f);

                        ConfigurationMigrator migrator = new ConfigurationMigrator();
                        migrator.Ensure(hasDatabase);

                        // Prepare clinical protocols
                        //retVal.GetService<ICarePlanService>().Repository = retVal.GetService<IClinicalProtocolRepositoryService>();
                    }
                    catch (Exception e)
                    {
                        retVal.m_tracer.TraceError(e.ToString());
                        throw;
                    }
                    finally
                    {
                        retVal.ConfigurationPersister.Save(retVal.Configuration);
                    }


                    if (!retVal.Configuration.GetSection <DiagnosticsConfigurationSection>().TraceWriter.Any(o => o.TraceWriterClassXml.Contains("Console")))
                    {
                        retVal.Configuration.GetSection <DiagnosticsConfigurationSection>().TraceWriter.Add(new TraceWriterConfiguration()
                        {
                            TraceWriter = typeof(ConsoleTraceWriter),
#if DEBUG
                            Filter = EventLevel.Informational
#else
                            Filter = EventLevel.Warning
#endif
                        });
                    }



                    // Start daemons
                    retVal.GetService <IThreadPoolService>().QueueUserWorkItem((o) => retVal.Start());
                }
        /// <summary>
        /// Starts the application context using in-memory default configuration for the purposes of
        /// configuring the software
        /// </summary>
        /// <returns><c>true</c>, if temporary was started, <c>false</c> otherwise.</returns>
        public static bool StartTemporary(ConsoleParameters consoleParms)
        {
            try
            {
                // Is autoconfiguration enabled on this
                var retVal = new MiniApplicationContext(consoleParms.InstanceName);
                retVal.SetProgress("Run setup", 0);

                ApplicationServiceContext.Current = ApplicationContext.Current = retVal;


                retVal.m_tracer = Tracer.GetTracer(typeof(MiniApplicationContext));
                var configuration = retVal.Configuration.GetSection <DiagnosticsConfigurationSection>();

                foreach (var tr in configuration.TraceWriter)
                {
                    Tracer.AddWriter(Activator.CreateInstance(tr.TraceWriter, tr.Filter, tr.InitializationData, configuration.Sources.ToDictionary(o => o.SourceName, o => o.Filter)) as TraceWriter, tr.Filter);
                }

                retVal.SetProgress("Loading configuration", 0.2f);
                var appService = retVal.GetService <IAppletManagerService>();

                if (consoleParms.References != null)
                {
                    MiniApplicationContext.LoadReferences(retVal, consoleParms.References);
                }

                // Does openiz.js exist as an asset?
                var oizJs = appService.Applets.ResolveAsset("/org.santedb.core/js/santedb.js");

                // Load all solution manifests and attempt to find their pathspec
                if (!String.IsNullOrEmpty(consoleParms.SolutionFile))
                {
                    LoadSolution(consoleParms.SolutionFile, appService);
                }


                // Load all user-downloaded applets in the data directory
                if (consoleParms.AppletDirectories != null)
                {
                    LoadApplets(consoleParms.AppletDirectories.OfType <String>(), appService);
                }

                if (oizJs?.Content != null)
                {
                    byte[] content  = appService.Applets.RenderAssetContent(oizJs);
                    var    oizJsStr = Encoding.UTF8.GetString(content, 0, content.Length);
                    oizJs.Content = oizJsStr + (appService as MiniAppletManagerService).GetShimMethods();
                }

                if (!consoleParms.Restore)
                {
                    retVal.GetService <IThreadPoolService>().QueueUserWorkItem((o) => retVal.Start());
                }

                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine("SanteDB FATAL: {0}", e.ToString());
                return(false);
            }
        }
        /// <summary>
        /// Load external references
        /// </summary>
        private static void LoadReferences(MiniApplicationContext context, StringCollection references)
        {
            var appService = context.GetService <IAppletManagerService>();

            // Load references
            foreach (var appletInfo in references)// Directory.GetFiles(this.m_configuration.GetSection<AppletConfigurationSection>().AppletDirectory)) {
            {
                try
                {
                    context.m_tracer.TraceInfo("Loading applet {0}", appletInfo);

                    String appletPath = appletInfo;

                    // Is there a pak extension?
                    if (Path.GetExtension(appletPath) != ".pak")
                    {
                        appletPath += ".pak";
                    }

                    if (!Path.IsPathRooted(appletInfo))
                    {
                        appletPath = Path.Combine(Environment.CurrentDirectory, appletPath);
                    }

                    // Does the reference exist in the current directory?
                    if (!File.Exists(appletPath))
                    {
                        appletPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Path.GetFileName(appletPath));
                    }

                    AppletPackage package = null;
                    if (!File.Exists(appletPath)) // Fetch from Repo
                    {
                        Console.WriteLine("Attempting to locate {0}", appletInfo);
                        var data = appletInfo.Split(';');
                        if (data.Length == 1)
                        {
                            package = PakMan.Repository.PackageRepositoryUtil.GetFromAny(appletInfo, null);
                        }
                        else
                        {
                            package = PakMan.Repository.PackageRepositoryUtil.GetFromAny(data[0], new Version(data[1]));
                        }
                    }
                    else
                    {
                        Console.WriteLine("Including {0}...", appletPath);
                        using (var fs = File.OpenRead(appletPath))
                        {
                            package = AppletPackage.Load(fs);
                        }
                    }

                    if (package == null)
                    {
                        throw new InvalidOperationException($"Cannot find reference {appletInfo}");
                    }

                    if (package is AppletSolution)
                    {
                        // Look for other applets with this
                        foreach (var itm in (package as AppletSolution).Include)
                        {
                            context.m_tracer.TraceInfo("Loading solution content project {0}", itm.Meta.Id);
                            appService.LoadApplet(itm.Unpack());
                        }
                    }
                    else
                    {
                        context.m_tracer.TraceInfo("Loading {0} v{1}", package.Meta.Id, package.Meta.Version);
                        // Is this applet in the allowed applets
                        appService.LoadApplet(package.Unpack());
                    }
                }
                catch (Exception e)
                {
                    context.m_tracer.TraceError("Loading applet {0} failed: {1}", appletInfo, e.ToString());
                    throw;
                }
            }
        }
Esempio n. 4
0
        private static void Main(string[] args)
        {
            AppDomain.CurrentDomain.AssemblyResolve += (o, e) =>
            {
                string pAsmName = e.Name;
                if (pAsmName.Contains(","))
                {
                    pAsmName = pAsmName.Substring(0, pAsmName.IndexOf(","));
                }

                var asm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => e.Name == a.FullName) ??
                          AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => pAsmName == a.GetName().Name);
                return(asm);
            };

            // Start up!!!
            var consoleArgs = new ParameterParser <ConsoleParameters>().Parse(args);

            consoleArgs.InstanceName = consoleArgs.InstanceName ?? "default";

            // Setup basic parameters
            String[] directory =
            {
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),      "santedb", "sdk", "ade", consoleArgs.InstanceName),
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "santedb", "sdk", "ade", consoleArgs.InstanceName)
            };

            foreach (var dir in directory)
            {
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }

            // Token validator
            TokenValidationManager.SymmetricKeyValidationCallback += (o, k, i) =>
            {
                return(MessageBox.Show(String.Format("Trust issuer {0} with symmetric key?", i), "Token Validation Error", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes);
            };
            ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, error) =>
            {
                if (certificate == null || chain == null)
                {
                    return(false);
                }
                else
                {
                    var valid = s_trustedCerts.Contains(certificate.Subject);
                    if (!valid && (chain.ChainStatus.Length > 0 || error != SslPolicyErrors.None))
                    {
                        if (MessageBox.Show(String.Format("The remote certificate is not trusted. The error was {0}. The certificate is: \r\n{1}\r\nWould you like to temporarily trust this certificate?", error, certificate.Subject), "Certificate Error", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                        {
                            return(false);
                        }
                        else
                        {
                            s_trustedCerts.Add(certificate.Subject);
                        }
                    }

                    return(true);
                    //isValid &= chain.ChainStatus.Length == 0;
                }
            };

            Console.WriteLine("SanteDB - Disconnected Client Debugging Tool");
            Console.WriteLine("Version {0}", Assembly.GetEntryAssembly().GetName().Version);
            Console.WriteLine(Assembly.GetEntryAssembly().GetCustomAttribute <AssemblyCopyrightAttribute>().Copyright);

            if (consoleArgs.Help || args.Length == 0)
            {
                new ParameterParser <ConsoleParameters>().WriteHelp(Console.Out);
            }
            else
            {
                if (consoleArgs.Reset)
                {
                    var appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "santedb", "sdk", "ade", consoleArgs.InstanceName);
                    var cData   = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "santedb", "sdk", "ade", consoleArgs.InstanceName);
                    if (Directory.Exists(appData))
                    {
                        Directory.Delete(cData, true);
                    }
                    if (Directory.Exists(appData))
                    {
                        Directory.Delete(appData, true);
                    }
                    Console.WriteLine("Environment Reset Successful");
                    return;
                }
                else if (consoleArgs.Restore)
                {
                    // Start a temporary session
                    MiniApplicationContext.StartTemporary(consoleArgs);

                    // Browse for backup
                    var dlgOpen = new OpenFileDialog()
                    {
                        CheckFileExists = true,
                        CheckPathExists = true,
                        DefaultExt      = "sdbk",
                        Filter          = "SanteDB Backup Files (*.sdbk)|*.sdbk",
                        Title           = "Restore from Backup"
                    };
                    if (dlgOpen.ShowDialog() != DialogResult.Cancel)
                    {
                        var pwdDialog = new frmKeyPassword(dlgOpen.FileName);
                        if (pwdDialog.ShowDialog() == DialogResult.OK)
                        {
                            // Attempt to unpack
                            try
                            {
                                new DefaultBackupService().RestoreFiles(dlgOpen.FileName, pwdDialog.Password, MiniApplicationContext.Current.GetService <IConfigurationPersister>().ApplicationDataDirectory);
                            }
                            catch (Exception e)
                            {
                                MessageBox.Show($"Error restoring {dlgOpen.Filter} - {e.Message}", "Error Restoring Backup");
                            }
                        }
                    }
                    return;
                }
                // Load reference assemblies.
                if (consoleArgs.Assemblies != null)
                {
                    foreach (var itm in consoleArgs.Assemblies)
                    {
                        try
                        {
                            Console.WriteLine("Loading reference assembly {0}...", itm);
                            Assembly.LoadFile(itm);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Error loading assembly {0}: {1}", itm, e);
                        }
                    }
                }

                MiniApplicationContext.ProgressChanged += (o, e) =>
                {
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine(">>> PROGRESS >>> {0} : {1:#0%}", e.ProgressText, e.Progress);
                    Console.ResetColor();
                };

                if (consoleArgs.BaseRefs)
                {
                    if (consoleArgs.References == null)
                    {
                        consoleArgs.References = new System.Collections.Specialized.StringCollection();
                    }

                    consoleArgs.References.AddRange(new string[]
                    {
                        "org.santedb.core",
                        "org.santedb.uicore",
                        "org.santedb.config",
                        "org.santedb.bicore",
                        "org.santedb.config.init",
                        "org.santedb.i18n.en"
                    });
                }

                try
                {
                    if (!MiniApplicationContext.Start(consoleArgs))
                    {
                        Console.WriteLine("Need to conifgure the system");
                        MiniApplicationContext.StartTemporary(consoleArgs);
                        MiniApplicationContext.Current.ConfigurationManager.SetAppSetting("http.bypassMagic", MiniApplicationContext.Current.ExecutionUuid.ToString());
                        // Forward
                        if (MiniApplicationContext.Current.GetService <AgsService>().IsRunning)
                        {
                            Process.Start("http://127.0.0.1:9200/#!/config/initialSettings");
                        }
                        else
                        {
                            MiniApplicationContext.Current.GetService <AgsService>().Started += (oo, oe) =>
                                                                                                Process.Start("http://127.0.0.1:9200/#!/config/initialSettings");
                        }
                    }
                    else
                    {
                        MiniApplicationContext.Current.ConfigurationManager.SetAppSetting("http.bypassMagic", MiniApplicationContext.Current.ExecutionUuid.ToString());
                        var appletConfig = MiniApplicationContext.Current.Configuration.GetSection <AppletConfigurationSection>();

                        // Forward
                        if (MiniApplicationContext.Current.GetService <AgsService>().IsRunning)
                        {
                            Process.Start("http://127.0.0.1:9200/#!/");
                        }
                        else
                        {
                            MiniApplicationContext.Current.GetService <AgsService>().Started += (oo, oe) =>
                                                                                                Process.Start("http://127.0.0.1:9200/#!/");
                        }
                    }

                    ManualResetEvent stopEvent = new ManualResetEvent(false);

                    Console.CancelKeyPress += (o, e) =>
                    {
                        stopEvent.Set();
                    };

                    MiniApplicationContext.Current.Stopped += (o, e) =>
                    {
                        // The host context has stopped by request of the system
                        stopEvent.Set();
                    };

                    Console.WriteLine("Press CTRL+C key to close...");
                    stopEvent.WaitOne();

                    if (MiniApplicationContext.Current?.IsRunning == true)
                    {
                        MiniApplicationContext.Current.Stop(); // stop
                    }
                    else
                    {
                        // Service stopped the context so we want to restart
                        Console.WriteLine("Will restart context, waiting for main teardown in 5 seconds...");
                        Thread.Sleep(5000);
                        var pi = new ProcessStartInfo(typeof(Program).Assembly.Location, string.Join(" ", args));
                        Process.Start(pi);
                        Environment.Exit(0);
                    }
                }
                finally
                {
                    Console.ResetColor();
                }
            }
        }