Beispiel #1
0
        public override void Configure(Funq.Container container)
        {
            AppSettings = new MultiAppSettingsBuilder()
                          .AddEnvironmentalVariables()
                          .AddTextFile("~/settings.txt".MapAbsolutePath())
                          .Build();


            var useRabbitMq = AppSettings.Get("rabbitmq:enable", false);

            if (useRabbitMq)
            {
                var rabbitMqConnectionString = AppSettings.Get("rabbitmq:connectionString", "localhost:5672");
                var rabbitMqUserName         = AppSettings.Get <string>("rabbitmq:userName", null);
                var rabbitMqPassword         = AppSettings.Get <string>("rabbitmq:passWord", null);
                container.Register <ICommandQueueService>(c => new RabbitCommandQueueService(rabbitMqConnectionString, rabbitMqUserName, rabbitMqPassword));

                var rabbitMqAlertConnectionString = AppSettings.Get("rabbitmqalert:connectionString", "localhost:5673");
                var rabbitMqAlertUserName         = AppSettings.Get <string>("rabbitmqalert:userName", null);
                var rabbitMqAlertPassword         = AppSettings.Get <string>("rabbitmqalert:passWord", null);
                container.Register <IAlertQueueService>(c => new RabbitAlertQueueService(rabbitMqAlertConnectionString, rabbitMqAlertUserName, rabbitMqAlertPassword));
            }
            else
            {
                container.Register <ICommandQueueService>(c => new CommandQueueService());
                container.Register <IAlertQueueService>(c => new AlertQueueService());
            }
        }
        public TestAppHost() : base(nameof(IntegrationTest), typeof(DeploymentService).Assembly)
        {
            var versionsJsv = new List <Version>
            {
                new Version
                {
                    VersionNumber = "3.5.3",
                    DownloadUrl   = "https://neo4j.com/artifact.php?name=neo4j-community-3.5.3-windows.zip",
                    ZipFileName   = "neo4j-community-3.5.3-windows.zip",
                    Architecture  = "V3"
                }
            }.ToJsv();

            AppSettings = new MultiAppSettingsBuilder()
                          .AddDictionarySettings(new Dictionary <string, string>
            {
                { AppSettingsKeys.Versions, versionsJsv },
                { AppSettingsKeys.Neo4jBasePath, @"c:\Neo4jManager" },
                { AppSettingsKeys.StartBoltPort, "7691" },
                { AppSettingsKeys.StartHttpPort, "7401" },
                { AppSettingsKeys.WatchDogInterval, "00:01:00" },
                { AppSettingsKeys.DefaultLeasePeriod, "00:05:00" },
                { AppSettingsKeys.ExpiryPeriod, "00:05:00" },
            })
                          .Build();
        }
Beispiel #3
0
        public AppHost(IWebHostEnvironment webHostEnvironment) : base("Neo4jManager", typeof(DeploymentService).Assembly)
        {
            var versions = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "versions.json"))
                           .FromJson <IEnumerable <Version> >()
                           .ToJsv();

            AppSettings = new MultiAppSettingsBuilder()
                          .AddEnvironmentalVariables()
                          .AddTextFile(Path.Combine(AppContext.BaseDirectory, "app.settings"))
                          .AddDictionarySettings(new Dictionary <string, string>
            {
                { AppSettingsKeys.Versions, versions }
            })
                          .Build();
        }
Beispiel #4
0
        public void Configure(IAppHost appHost)
        {
            Log.Debug("starting DiskAnalysisServicesPlugin.Configure");

            // Populate this Plugin's Application Configuration Settings
            // Location of the files will depend on running as LifeCycle Production/QA/Dev as well as Debug and Release settings
            var pluginAppSettings = new MultiAppSettingsBuilder()
                                    // Command line flags have highest priority
                                    // next in priority are  Environment variables
                                    //.AddEnvironmentalVariables()
                                    // next in priority are Configuration settings in a text file relative to the current working directory at the point in time when this method executes.
                                    .AddTextFile(pluginSettingsTextFileName)
                                    // Builtin (compiled in) have the lowest priority
                                    .AddDictionarySettings(DefaultConfiguration.Configuration())
                                    .Build();

            // Key names in the cache for Configuration settings for a Plugin consist of the namespace and the string .Config
            // Key names in the appSettings of a Plugin for Configuration settings may or may not have the prefix
            // Compare the two lists of Configuration setting keys...

            // create a copy of the keys from AppSettings ensuring all are prefixed with the namespace and .Config
            var configKeyPrefix           = myNamespace + ".Config.";
            var lengthConfigKeyPrefix     = configKeyPrefix.Length;
            var appSettingsConfigKeys     = pluginAppSettings.GetAllKeys();
            var fullAppSettingsConfigKeys = appSettingsConfigKeys.Select(x => x.IndexOf(configKeyPrefix) >= 0 ? x : configKeyPrefix + x);

            // Get this namespaces configuration settings from the cache
            var cacheClient     = appHost.GetContainer().Resolve <ICacheClient>();
            var cacheConfigKeys = cacheClient.GetKeysStartingWith(configKeyPrefix);

            // Compare the configuration retrieved from the cache with the configuration from the built-in defaults, the text files, and the environment variables
            // If the cache is missing a ConfigKey, update the cache with the ConfigKey and its value from the appSettings
            var excludedConfigKeys   = new HashSet <string>(cacheConfigKeys);
            var additionalConfigKeys = fullAppSettingsConfigKeys.Where(ck => !excludedConfigKeys.Contains(ck));

            foreach (var ck in additionalConfigKeys)
            {
                cacheClient.Set <string>(ck, pluginAppSettings.GetString(ck.Substring(lengthConfigKeyPrefix)));
            }
            // If both the cache and the appSettings have the same ConfigKey, and the same value, do nothing
            // If both the cache and the appSettings have the same ConfigKey, and the values are different,
            // If the cache has a ConfigKey and the appSettings does not have that ConfigKey
            // Set a flag indicating the need to dialog with the user to resolve the cache vs. appSettings discrepancies
            bool configurationsMatch = true; // (appSettingsConfigkeys.Count == cacheConfigkeys.Count) ;


            // Populate this Plugin's Gateways
            // Location of the files will depend on running as LifeCycle Production/QA/Dev as well as Debug and Release settings
            //var pluginGateways = new MultiGatewaysBuilder()
            // Command line flags have highest priority
            // next in priority are  Environment variables
            //.AddEnvironmentalVariables()
            // next in priority are Configuration settings in a text file relative to the current working directory at the point in time when this method executes.
            //.AddTextFile(pluginGatewaysTextFileName)
            // Builtin (compiled in) have the lowest priority
            //.AddDictionarySettings(DefaultGateways.Configuration())
            //.Build();



            // Create a Gateways collection from the txt file
            //ConcurrentObservableDictionary<string, IGateway> gateways = new ConcurrentObservableDictionary<string, IGateway>();
            //gateways.Add("GoogleMapsGeoCoding", new GatewayBuilder().Build());
            // Create the Plugin's data structure. There should only be a single instance.
            // Every Property matching a ConfigKey gets/sets the value of the matching ConfigKey in the cache
            // ConfigKey Properties do not have to be set in the constructor because the cache was setup before calling the constructor


            DiskAnalysisServicesData diskAnalysisServicesData = new DiskAnalysisServicesData(appHost, new ConcurrentObservableDictionary <string, decimal>(), onPluginRootCollectionChanged, onPluginRootPropertyChanged);

            // copy the most recent configuration settings to the Data
            // hmm should be a way to make sure the Data has a Property for each configuration setting, and to populate the initial Data with the cache value
            // DiskAnalysisServicesData.GoogleAPIKeyEncrypted = cacheClient.Get<string>(configKeyPrefix + "GoogleAPIKeyEncrypted");
            //DiskAnalysisServicesData.HomeAwayAPIKeyEncrypted = cacheClient.Get<string>(configKeyPrefix + "HomeAwayAPIKeyEncrypted");
            //DiskAnalysisServicesData.HomeAway_API_URI = cacheClient.Get<string>(configKeyPrefix + "HomeAway_API_URI");
            // DiskAnalysisServicesData.Google_API_URI = cacheClient.Get<string>(configKeyPrefix + "Google_API_URI");
            //DiskAnalysisServicesData.UriHomeAway_API_URI = cacheClient.Get<Uri>(configKeyPrefix + "UriHomeAway_API_URI");
            //DiskAnalysisServicesData.UriGoogle_API_URI = cacheClient.Get<Uri>(configKeyPrefix + "UriGoogle_API_URI");

            // and pass the Plugin's data structure to the container so it will be available to every other module and services
            appHost.GetContainer().Register(c => diskAnalysisServicesData);



            // ToDo: enable the mechanisms that monitors each GUI-specific data sensor, and start them running
        }
Beispiel #5
0
        /// <summary>
        /// Application specific configuration
        /// This method should initialize any IoC resources utilized by your web service classes.
        /// </summary>
        public override void Configure(Container container)
        {
            // inject the concrete logging implementation
            Log.Debug($"Entering AppHost.Configure method, container is {container.ToString()}");

            // AppSettings is a first class object on the Container, so it will be auto-wired
            // In any other assembly, AppSettings is read-only, so it must be populated in this assembly
            // Location of the configuration files will depend on running as LifeCycle Production/QA/Dev as well as Debug and Release settings

            //It would be nice if ServiceStack implemented the User Secrets pattern that ASP Core provides
            // The Environment variable may define the location of a text file to add to the AppSettings
            string indirectSettingsTextFilepath;

            try {
                indirectSettingsTextFilepath = Environment.GetEnvironmentVariable(agentEnvironmentIndirectSettingsTextFileNameKey);
            }
            catch (SecurityException e) {
                Log.Error($"{cannotReadEnvironmentVariablesSecurityExceptionMessage}: {e.Message}");
                throw new SecurityException(cannotReadEnvironmentVariablesSecurityExceptionMessage, e);
            }

            // ToDo: If the Environment variable does define a location for another text fle, ensure it can be read
            if (indirectSettingsTextFilepath != null)
            {
                try { }
                catch { }
            }
            // Create the AppSettingsBuilder, and add command line arguments to it
            var multiAppSettingsBuilder = new MultiAppSettingsBuilder();

            // Highest priority is any command line variable values, so add command line arguments to the AppSettingsBuilder
            // ToDo: .Add??
            // Next in priority are all environment values, so append AddEnvironmentalVariables to the AppSettingsBuilder
            multiAppSettingsBuilder.AddEnvironmentalVariables();
            // Next in priority are contents of any indirect files mentioned in the environment variables (e.g. User Secrets )
            if (indirectSettingsTextFilepath != null)
            {
                multiAppSettingsBuilder.AddTextFile(indirectSettingsTextFilepath);
            }
            // Next in priority are any configuration settings in a text file named on the command line.
            // ToDo: if a configuration settings text file is specified on the command line, ensure we have permission to read it
            // ToDo: append AddTextFile for configuration settings in a text file specified on the command line to the AppSettingsBuilder
            // Next in priority are any configuration settings in a text file named as a constant string in the app.
            // Location of the text file is relative to the current working directory at the point in time when this method executes.
            // If this file does not exist, it is not considered an error, but if it does exist, not having read permission is an error
            // ToDo: if a configuration settings text file is specified as a constant string in the app, ensure we have permission to read it
            // ToDo: if it exists, append AddTextFile for configuration settings in a text file specified as a constant string in the app to the AppSettingsBuilder
            multiAppSettingsBuilder.AddTextFile(agentSettingsTextFileNameString);
            // Next in priority are any configuration settings in the application config file (AKA AceAgent.exe.config at runtime)
            // Location of the application config file is relative to the current working directory at the point in time when this method executes.
            // If this file does not exist, it is not considered an error, but if it does exist, not having read permission is an error
            // ToDo: if a application config file  is specified as a constant string in the app, ensure we have permission to read it
            // ToDo: if it exists, append AddTextFile for configuration settings in a text file specified as a constant string in the app to the AppSettingsBuilder
            multiAppSettingsBuilder.AddAppSettings()
            // Builtin (compiled in) configuration settings have the lowest priority
            // Add these to the AppSettingsBuilder
            .AddDictionarySettings(DefaultConfiguration.Configuration());
            //Build the AppSettings
            AppSettings = multiAppSettingsBuilder.Build();

            // Create the BaseServices data structure and register it in the container
            //  The AppHost (here, ServiceStack running as a Windows service) has some configuration that is common
            //  to both Frameworks (.Net and .Net Core), which will be setup in a common assembly, so this instance of
            //  the appHost is being passed to the BaseServicesData constructor.
            //  this also registers a BaseServicesData instance in the container
            // ToDo: implement Singleton pattern for BaseServicesData in the DI Container
            var baseServicesData = new BaseServicesData(this);

            container.Register <BaseServicesData>(c => baseServicesData);

            // ToDo: Get the list of plugins to install from the configuration settings, currently hard coded
            // Create the list of PlugIns to load
            var plugInList = new List <IPlugin>()
            {
                //new RealEstateServicesPlugin(),
                //new MinerServicesPlugin(),
                new DiskAnalysisServicesPlugin(),
                new GUIServicesPlugin()
            };

            // Load each plugin here.
            foreach (var pl in plugInList)
            {
                Plugins.Add(pl);
            }

            // ToDo: See Issue #8
            // ToDo place a static, deep-copy of the current application'instance of the configuration settings as the first object in the application's configuration settings history list.

            // start all the timers
            Log.Debug("In AppHost.Configure: starting all timers");
            var timers = Container.Resolve <Dictionary <string, System.Timers.Timer> >();
            var longRunningTasksCheckTimer = timers[Ace.Agent.BaseServices.BaseServicesData.LongRunningTasksCheckTimerName];

            longRunningTasksCheckTimer.Start();

            /*
             * // ToDo: create a NotifyIcon equivalent for a Windows Service or Linux Daemon. Notifiy Icon itself will not work, as that is for WinForms only
             * Log.Debug("in AppHost.Configure: Create a NotifyIcon for AceCommander");
             * Application.EnableVisualStyles();
             * Application.SetCompatibleTextRenderingDefault(false);
             * NotifyIcon notifyIcon1 = new NotifyIcon();
             * ContextMenu contextMenu1 = new ContextMenu();
             * MenuItem menuItem1 = new MenuItem();
             * contextMenu1.MenuItems
             *  .AddRange(new MenuItem[] { menuItem1 });
             * menuItem1.Index=0;
             * menuItem1.Text="E&xit";
             * menuItem1.Click+=new EventHandler(menuItem1_Click);
             * notifyIcon1.Icon=new Icon("atap.ico");
             * notifyIcon1.Text="AceCommander";
             * notifyIcon1.ContextMenu=contextMenu1;
             * notifyIcon1.Visible=true;
             * // Log.Debug("Calling a Web Forms Application instance's static Run method");
             * // Application.Run();
             * // notifyIcon1.Visible = false;
             * Log.Debug("NotifyIcon for AceCommander created");
             */
            Log.Debug("Leaving AppHost.Configure");
        }
Beispiel #6
0
        public void Configure(IAppHost appHost)
        {
            Log.Debug("starting GUIServicesPlugin.Configure");

            // Populate this Plugin's Application Configuration Settings
            // Location of the files will depend on running as LifeCycle Production/QA/Dev as well as Debug and Release settings
            var pluginAppSettings = new MultiAppSettingsBuilder()
                                    // Environment variables have highest priority
                                    //.AddEnvironmentalVariables()
                                    // Configuration settings in a text file relative to the current working directory at the point in time when this method executes.
                                    .AddTextFile(pluginSettingsTextFileNameString)
                                    // Builtin (compiled in) have the lowest priority
                                    .AddDictionarySettings(DefaultConfiguration.Configuration())
                                    .Build();

            // tell ServiceStack where to find the physical base of the GUI static files
            // In RELEASE mode, the physical path of the root of the GUI should be located in a subdirectory relative to the location of the assembly that holds Program
            // In DEBUG mode, the physical path of the root of the GUI will be located somewhere "above and to the side" of the ServiceStack Plugin project
            string physicalRootPath =
                Path
                .GetDirectoryName(
                    Assembly
                    .GetExecutingAssembly()
                    .Location);

            Log.Debug($"in GUIServicesPlugin.Configure, initial physicalRootPath (GetExecutingAssembly().Location) = {physicalRootPath}");
            string relativeRootPathValue;

#if DEBUG
            // set the physicalRootPath of the GUI code to the appSetting for the development RelativeRootPathKey relative to the location of this plugin's assembly
            // verify key exists, else throw exception
            if (!pluginAppSettings.Exists(debugRelativeRootPathKey) ||
                (pluginAppSettings.GetString(debugRelativeRootPathKey) == string.Empty))
            {
                throw new Exception(debugRelativeRootPathKeyOrValueNotFoundExceptionMessage);
            }
            relativeRootPathValue = pluginAppSettings.GetString(debugRelativeRootPathKey);
#else
            // set the physicalRootPath of the GUI code to the appSetting for the production RelativeRootPathKey relative to the location of this plugin's assembly
            // verify key exists, else throw exception
            if (!pluginAppSettings.Exists(productionRelativeRootPathKey) || (pluginAppSettings.GetString(productionRelativeRootPathKey) == ""))
            {
                throw new Exception(productionRelativeRootPathKeyOrValueNotFoundExceptionMessage);
            }
            relativeRootPathValue = pluginAppSettings.GetString(productionRelativeRootPathKey);
#endif
            Log.Debug($"in GUIServicesPlugin.Configure, relativeRootPathValue = {relativeRootPathValue}");
            // Use these for checking for invalid characters in the appSettings RelativeRootPath values
            char[] invalidChars = Path.GetInvalidPathChars();
            bool   valid        = !relativeRootPathValue.Any(x => invalidChars.Contains(x));

            if (!valid)
            {
                throw new Exception(relativeRootPathValueContainsIlegalCharacterExceptionMessage);
            }
            Log.Debug($"in GUIServicesPlugin.Configure, physicalRootPath = {physicalRootPath}, relativeRootPathValue = {relativeRootPathValue}");
            physicalRootPath = PathUtils.CombinePaths(physicalRootPath, relativeRootPathValue);
            Log.Debug($"in GUIServicesPlugin.Configure, ");

            // use an appSetting for the VirtualRootPath
            string virtualRootPath;
            // verify key exists, else throw exception. String.Empty is allowed
            if (!pluginAppSettings.Exists(virtualRootPathKey))
            {
                throw new Exception(virtualRootPathKeyOrValueNotFoundExceptionMessage);
            }
            virtualRootPath = pluginAppSettings.GetString(virtualRootPathKey);
            // Map the Virtual root Dir to the physical path of the root of the GUI
            // Wrap in a try catch block in case the root Path does not exist
            try {
                appHost.AddVirtualFileSources
                .Add(new FileSystemMapping(virtualRootPath, physicalRootPath));
            }
            catch {
                throw;
                // ToDo: figure out how to log this and fallback to something useful
            }

            Log.Debug($"in GUIServicesPlugin.Configure, virtualRootPath = {virtualRootPath}");

            // Blazor requires the delivery of static files ending in certain file suffixes.
            // SS disallows many of these by default, so here we tell SS to allow certain file suffixes
            appHost.Config.AllowFileExtensions.Add("dll");
            appHost.Config.AllowFileExtensions.Add("json");
            appHost.Config.AllowFileExtensions.Add("pdb");

            // per conversation with Myth at SS, the default behaviour, for URi "/" is to return the content of wwwroot/index.html
            appHost.Config.DefaultRedirectPath = "/index.html";
            // ToDo: if the GUI configuration specifies that the GUI has GUI-specific data sensor that can and should be monitored, attach the event handlers that will respond to changes in the monitored data structures
            // ToDo: setup the mechanisms that monitors the GUI

            // create the plugIn's data object and pass it to the container so it will be available to every other module and services
            appHost.GetContainer()
            .Register <GUIServicesData>(d => new GUIServicesData(pluginAppSettings));

            // ToDo: enable the mechanisms that monitors each GUI-specific data sensor, and start them running
        }
Beispiel #7
0
        /// Configure its PlugInAppSettings and ConfigurationData
        public void BeforePluginsLoaded(IAppHost appHost)
        {
            // Get the IHostEnvironment type object from the ServiceStack Container
            HostEnvironment = appHost.GetContainer().Resolve <Microsoft.Extensions.Hosting.IHostEnvironment>();
            // Determine the environment this PlugIn has been activated in
            string envName = HostEnvironment.EnvironmentName;

            // Populate this PlugIn's AppSettings Configuration Settings and place it in the appSettingsDictionary
            // ToDo: figure out how to place /resolve text files from relative to the location of the PlugIn assembly
            var pluginAppSettingsBuilder = new MultiAppSettingsBuilder();

            // ToDo: command line settings have the highest priority
            // Environment variables have 2nd highest priority
            pluginAppSettingsBuilder.AddEnvironmentalVariables();
            // third priority are Non-Production Configuration settings in a text file
            if (!this.HostEnvironment.IsProduction())
            {
                var settingsTextFileName = Ace.Agent.GUIServices.StringConstants.PluginSettingsTextFileName + '.' + envName + StringConstants.PluginSettingsTextFileSuffix;
                // ToDo: ensure it exists and the ensure we have permission to read it
                // ToDo: Security: There is something called a Time-To-Check / Time-To-Use vulnerability, ensure the way we check then access the text file does not open the program to this vulnerability
                pluginAppSettingsBuilder.AddTextFile(settingsTextFileName);
            }
            // next in priority are Production Configuration settings in a text file
            pluginAppSettingsBuilder.AddTextFile(StringConstants.PluginSettingsTextFileName + StringConstants.PluginSettingsTextFileSuffix);
            // BuiltIn (compiled in) have the lowest priority
            pluginAppSettingsBuilder.AddDictionarySettings(DefaultConfiguration.Production);

            // Populate the PlugInAppSettings property for this PlugIn from the builder
            PlugInAppSettings = pluginAppSettingsBuilder.Build();
            // Populate the ConfigurationData property with an empty configuration data instance
            // populate the GUIS property of the ConfigurationData with a new GUIS having an empty list of GUIs
            ConfigurationData      = new ConfigurationData();
            ConfigurationData.GUIS = new GUIS()
            {
                GUIs = new List <GUI>()
            };
            // Get the GUIMaps POCO from PlugInAppSettings
            // Ensure the PlugInAppSettings has a non-empty ConfigKey for the GUIMaps
            if (!PlugInAppSettings.Exists(StringConstants.GUIMapsConfigKey) ||
                (PlugInAppSettings.GetString(StringConstants.GUIMapsConfigKey) == string.Empty))
            {
                throw new Exception(StringConstants.GUISKeyOrValueNotFoundExceptionMessage);
            }
            // ToDo: Security: this is a place where character strings from external sources are processed, check carefully
            //  any typo in the text file can make the conversion to a POCO break
            GUIMaps gUIMaps;

            try
            {
                gUIMaps = PlugInAppSettings.Get <GUIMaps>(StringConstants.GUIMapsConfigKey);
            }
            catch (Exception)
            {
                //ToDo: Better exception handling
                throw;
            }
            // ToDo: Throw exception if the IEnumerable count = 0
            char[] invalidChars = Path.GetInvalidPathChars();

            // Loop over each GUI defined in pluginAppSettings GUIs, create a virtualFileMapping
            foreach (GUIMap gUIMap in gUIMaps._GUIMaps)
            {
                if (gUIMap.RelativeToContentRootPath.Any(x => invalidChars.Contains(x)))
                {
                    throw new Exception(StringConstants.RelativeRootPathValueContainsIlegalCharacterExceptionMessage);
                }
                // The GenericHost's ContentRootPath is found on the HostEnvironment injected during the .ctor
                var physicalPath = Path.Combine(this.HostEnvironment.ContentRootPath, gUIMap.RelativeToContentRootPath);
                //Log.Debug("in GUIServicesPlugin.Configure, physicalPath = {PhysicalPath}, ContentRootPath = {ContentRootPath} relativeRootPathValue = {RelativeToContentRootPath}", physicalPath, this.HostEnvironment.ContentRootPath, gUIMap.RelativeToContentRootPath);
                //Log.Debug("in GUIServicesPlugin.Configure, index.html exists in physicalpath = {0}", File.Exists(Path.Combine(physicalPath, "index.html")));
                //Log.Debug("in GUIServicesPlugin.Configure, virtualRootPath = {GUIMapVirtualRootPath}", gUIMap.VirtualRootPath);

                // if the VirtualRootPath is empty, setup the webserver's wwwroot to point to the physicalpath
                if (gUIMap.VirtualRootPath == null)
                {
                    Log.Debug("current wwwroot = {Wwwroot}", (appHost as AppHostBase).HostingEnvironment.WebRootPath);
                    // If the webserver's wwwroot is already populated, throw an exception
                    // Set the WebRootPath to the physicalpath
                    // (appHost as AppHostBase).HostingEnvironment.WebRootPath = physicalPath;
                    // Log.Debug("current wwwroot = {Wwwroot}", (appHost as AppHostBase).HostingEnvironment.WebRootPath);
                    appHost.AddVirtualFileSources
                    .Add(new FileSystemMapping("", physicalPath));
                }
                else
                {
                    // Map the virtualRootPath to the physicalpath of the root of the GUI
                    // Wrap in a try catch block in case the physicalRootPath does not exists
                    // ToDo: test for failure condition instead of letting it throw an exception
                    try
                    {
                        appHost.AddVirtualFileSources
                        .Add(new FileSystemMapping(gUIMap.VirtualRootPath, physicalPath));
                    }
                    catch (Exception e)
                    {
                        // ToDo: research how best to log an exception with Serilog, ServiceStack and/or MS
                        // ToDo: USe stringconstant for exception message
                        Log.Debug(e, "in GUIServicesPlugin.Configure, Adding a new VirtualFileSource failed with : {Message}", e.Message);
                        // ToDo wrap in an Aggregate when doing loop
                        throw;
                        // ToDo: figure out how to log this and fallback to something useful
                    }
                }
                // ToDo: Get Version and Description from assembly metadata
                ConfigurationData.GUIS.GUIs.Add(new GUI()
                {
                    Version = "0.0.1", Description = "A sample", GUIMap = gUIMap
                });
            }

            // ToDo: add support for probing for additional GUIS at runtime, add them to ConfigurationData.GUIS.GUIs

            // If a request comes in for the root of the web site, redirect it to the default GUI's index.html file
            // ToDo: Security: this is a place where character strings from external sources are processed, check carefully
            // Get the DefaultGUIVirtualRootPath from PlugInAppSettings
            // Ensure the PlugInAppSettings has a  (possibly empty) ConfigKey for the DefaultGUIVirtualRootPath
            if (!PlugInAppSettings.Exists(StringConstants.DefaultGUIVirtualRootPathConfigKey))
            {
                throw new Exception(StringConstants.DefaultGUIVirtualRootPathKeyOrValueNotFoundExceptionMessage);
            }
            // Ensure the value of the defaultGUIVirtualRootPath matches the value of the VirtualRootPath of one of the GUIMaps
            string defaultGUIVirtualRootPath = PlugInAppSettings.Get <string>(StringConstants.DefaultGUIVirtualRootPathConfigKey);
            GUI    defaultGUI;

            try {
                defaultGUI = ConfigurationData.GUIS.GUIs.Single(gUI => gUI.GUIMap.VirtualRootPath == defaultGUIVirtualRootPath);
            } catch {
                throw new Exception(StringConstants.DefaultGUIVirtualRootPathDoesNotMatchExactlyOneGUIVirtualRootPathExceptionMessage);
            }

            // Set the default redirect. If defaultGUIVirtualRootPath is null, ensure there is not a double // in the  path
            appHost.Config.DefaultRedirectPath = String.Format(StringConstants.DefaultRedirectPathTemplate, defaultGUI.GUIMap.VirtualRootPath);


            // Blazor requires the delivery of static files ending in certain file suffixes.
            // SS disallows some of these by default, so here we tell SS to allow certain file suffixes
            appHost.Config.AllowFileExtensions.Add("dll");
            appHost.Config.AllowFileExtensions.Add("json");
            appHost.Config.AllowFileExtensions.Add("pdb");

            // Blazor requires CORS support, enable the ServiceStack CORS feature
            appHost.Plugins.Add(new CorsFeature(
                                    allowedMethods: "GET, POST, PUT, DELETE, OPTIONS",
                                    allowedOrigins: "*",
                                    allowCredentials: true,
                                    allowedHeaders: "content-type, Authorization, Accept"));

            // create the PlugIn's data object
            GUIServicesData gUIServicesData = new GUIServicesData(PlugInAppSettings, ConfigurationData);

            // Pass the Plugin's data structure to the container so it will be available to every other module and services
            appHost.GetContainer().Register <GUIServicesData>(d => gUIServicesData);

            // ToDo: enable the mechanisms that monitors each plugin-specific data sensor, and start them running
            // ToDo: Need to figure out if / how a PlugIn can add a PlugIn to the parent AppHost, if it detects there is a dependency
        }
Beispiel #8
0
        // Configure your AppHost with the necessary configuration and dependencies your App needs
        public override void Configure(Container container)
        {
            Plugins.Add(new SharpPagesFeature()); // enable server-side rendering, see: https://sharpscript.net/docs/sharp-pages

            // This is already done for you however in many cases you may want to add
            // your own custom items that will be a part of this cascading app settings provider
            MultiAppSettingsBuilder multiAppSettingsBuilder = new MultiAppSettingsBuilder();

            multiAppSettingsBuilder
            .AddNetCore(_coreConfig);     // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#default-configuration

            // You can add text files or your own dictionary of custom values if you want

            AppSettings = multiAppSettingsBuilder.Build();
            JsConfig.TreatEnumAsInteger = true;

            SetConfig(new HostConfig
            {
                UseCamelCase                   = true,
                UseSameSiteCookies             = true,
                AddRedirectParamsToQueryString = true,
                DebugMode = AppSettings.Get(nameof(HostConfig.DebugMode), HostingEnvironment.IsDevelopment()),
            });

            // for our app we will use an inmemory database.  This can be replaced with no
            // code changes for sql server, mysql or any of the ormlite providers

            Plugins.Add(new AutoQueryDataFeature()
            {
                MaxLimit = int.MaxValue
            });

            Plugins.Add(new AdminFeature());
            container.Register <IDbConnectionFactory>(c => new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));

            using (var db = container.Resolve <IDbConnectionFactory>().Open())
            {
                db.CreateTableIfNotExists <PostLog>();
            }



            GatewayRequestFilters.Add((req, dto) =>
            {
                if (dto is PostRequest || dto is PostQueryRequest)
                {
                    using (var db = Resolve <IDbConnectionFactory>().Open())
                    {
                        using (var trans = db.OpenTransaction())
                        {
                            db.Insert <PostLog>(new PostLog()
                            {
                                EntryDate   = DateTime.UtcNow,
                                Identifier  = (dto is PostRequest) ? ((PostRequest)dto).Id : string.Empty,
                                RequestType = dto.ToString(),
                                FilterType  = FilterType.GatewayFilter
                            });
                            trans.Commit();
                        }
                    }
                }
            });

            GlobalRequestFilters.Add((req, res, dto) =>
            {
                if (dto is PostRequest || dto is PostQueryRequest)
                {
                    using (var db = Resolve <IDbConnectionFactory>().Open())
                    {
                        using (var trans = db.OpenTransaction()) {
                            db.Insert <PostLog>(new PostLog()
                            {
                                EntryDate   = DateTime.UtcNow,
                                Identifier  = (dto is PostRequest) ? ((PostRequest)dto).Id : string.Empty,
                                RequestType = dto.GetType().ToString(),
                                FilterType  = FilterType.RequestFilter
                            });
                            trans.Commit();
                        }
                    }
                }
            });

            container.AddTransient <IServiceGatewayFactory>(() => new CustomServiceGatewayFactory());
        }