Configuration Monitoring

QBO is designed to run on a server farm, and enables power users to alter configuration settings which, in some cases, need to be propagated to all servers in a server farm. Such propagation is accomplished via Configuration Monitoring. Specifically, a ConfigurationMonitor class does the following:
  • scans the bin folder for DLLs that include a ConfigurationMonitorAttribute attribute (pointing to some method to run), and registers the monitoring method
  • starts a timer
  • each time it's timer elapses, executes each registered monitoring method
For websites, initiating configuration monitoring is done via the Application_Start method found in Global.asax.

As of this writing, there are three monitoring methods in the QBO standard deployment:
  • ConfigurationEntry: enables overrides of any .config file based on the BaseConfiguration class
    • scans the ConfigurationEntry table for recent changes, and loads the configuration data into the application domain's memory
  • SystemDefault: enables overrides of application settings
    • scans the SystemDefault table for application setting changes, and writes any application settings to web.config
  • CachedFile: enables overrides of standard XSLTs
    • scans the ConfiguationEntry table for 'FileOverride' entries, and copies them from a configured FileObject (e.g. Amazon S3, Azure

Configuration Entry

Upon detecting a ConfigurationEntry table change, the ConfigurationEntry corresponding collection is updated to contain the ConfigurationXml value that was saved to the database. Consider the following example:
  • A new statement called SCRASelect is added under the Contact module resulting in a record being added to ConfigurationEntry. The ConfigurationEntry record contains:
    • Source = Contact.config
    • ConfigurationType = qbo.Application.Configuration.DbStatementCollection
    • ConfigurationKey = SCRASelect
    • ConfigurationXml = {Statement Xml}
    • UpdatedDate = {Date Added}
  • The ConfigurationMonitor will detect the new record based on last poll date.
  • ConfiguraitonMonitor will invoke the Update method. The Update method must be implement in each class that inherits from BaseConfiguration. In this case it will Deserialize the ConfigurationXml which updates Contact statement collection and then wires the statement into the Contact configuration) 

Targeting Specific Servers

In some case, including multi-tenant installations and code roll-outs, it is useful to have configuration entries that apply to some servers, but not others. This can be accomplished by using the qbo.Application.Properties.Settings.ConfigurationFilter application setting. For example:

<setting name="ConfigurationFilter" serializeAs="String">

When a web.config file includes this setting, the server's ConfigurationEntry/Monitor method will include ConfigurationEntry rows where:
  • ConfigurationEntry.Filter is NULL, or
  • ConfigurationEntry.Filter = qbo.Application.Properties.Settings.ConfigurationFilter
For example, assume:
  • you are deploying a new OCR plugin (qbo.Attachment.GoogleDrive) as part of a code deployment. 
  • machines P1, P2, P3 and P4 contain your 'old' code base (without the OCR plugin)
  • machines P5, P6, P7 and P8 contain your 'new' code base (with the OCR plugin)
  • you intend to deploy a setup package (Setup.OCR.xml)
    • this includes an IService entry for Attachment.config so users can call Attachment/OCR
If you run the Setup.OCR.xml package as-is, all machines (P1..P8) will attempt to wire an IService entry to qbo.Attachment.GoogleDrive.dll. Machines P1..P4 don't have qbo.Attachment.GoogleDrive.dll, so they will encounter an error.

This error can be avoid as follows:
  • In the web.config file for P5..P8, set the ConfigurationFilter to some value that is different than P1..P4 (e.g. 'PROD-2016-09-15')
  • Edit Setup.OCR.xml manually, adding a Filter node to each ConfigurationEntry: <Filter>PROD-2016-09-15</Filter>
  • Run the manually edited setup package against any server
This will create ConfigurationEntry rows that will only be read by servers P5..P8.  Servers P1..P4 will ignore those rows. It also means that servers P1..P4 will not be able to call any newly created Attachment/OCR method, but that's true prior to the code deployment anyway.

Once machines P1..P4 have been 'decommissioned', you should run the following SQL to ensure you keep Attachment/OCR available for future code deployments:

UPDATE ConfigurationEntry SET Filter = NULL WHERE Filter = 'PROD-2016-09-15'