Skip to content
Snippets Groups Projects
Commit 09825305 authored by Niko Ehrenfeuchter's avatar Niko Ehrenfeuchter :keyboard:
Browse files

Allow configuration to be spread across two separate files.

One file ("config.common.xml") containing site-global configuration
settings, the other one (the file name equals the host name with a
".xml" suffix) containing host-specific settings.

Both files use the same syntax and may contain the same setting
attributes with the host-specific one having priority over the
site-global one.

Refers to #18
parent c1240219
Branches
Tags
No related merge requests found
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using NLog;
......@@ -33,15 +34,38 @@ namespace ATxCommon.Serializables
throw new SettingsPropertyIsReadOnlyException("The config file must not be written by the service!");
}
public static ServiceConfig Deserialize(string file) {
Log.Debug("Trying to read service configuration XML file: [{0}]", file);
var serializer = new XmlSerializer(typeof(ServiceConfig));
/// <summary>
/// Load the host specific and the common XML configuration files, combine them and
/// deserialize them into a ServiceConfig object. The host specific configuration file's
/// name is defined as the hostname with an ".xml" suffix.
/// </summary>
/// <param name="path">The path to the configuration files.</param>
/// <returns>A ServiceConfig object with validated settings.</returns>
public static ServiceConfig Deserialize(string path) {
ServiceConfig config;
using (var reader = XmlReader.Create(file)) {
var commonFile = Path.Combine(path, "config.common.xml");
var specificFile = Path.Combine(path, Environment.MachineName + ".xml");
// for parsing the configuration from two separate files we are using the default
// behaviour of the .NET XmlSerializer on duplicates: only the first occurrence is
// used, all other ones are silentley being discarded - this way we simply append the
// contents of the common config file to the host-specific and deserialize then:
var common = XElement.Load(commonFile);
Log.Debug("Loaded common configuration XML file: [{0}]", commonFile);
var combined = XElement.Load(specificFile);
Log.Debug("Loaded host specific configuration XML file: [{0}]", specificFile);
combined.Add(common.Nodes());
Log.Trace("Combined XML structure:\n\n{0}\n\n", combined);
using (var reader = XmlReader.Create(new StringReader(combined.ToString()))) {
Log.Debug("Trying to parse combined XML.");
var serializer = new XmlSerializer(typeof(ServiceConfig));
config = (ServiceConfig) serializer.Deserialize(reader);
}
ValidateConfiguration(config);
Log.Debug("Finished deserializing service configuration XML file.");
Log.Debug("Successfully parsed and validated configuration XML.");
return config;
}
......
......@@ -21,7 +21,7 @@ namespace ATxConfigTest
Layout = @"${date:format=yyyy-MM-dd HH\:mm\:ss} [${level}] (${logger}) ${message}",
};
logConfig.AddTarget("console", consoleTarget);
var logRuleConsole = new LoggingRule("*", LogLevel.Debug, consoleTarget);
var logRuleConsole = new LoggingRule("*", LogLevel.Trace, consoleTarget);
logConfig.LoggingRules.Add(logRuleConsole);
LogManager.Configuration = logConfig;
......@@ -29,13 +29,12 @@ namespace ATxConfigTest
if (args.Length > 0)
baseDir = args[0];
var configPath = Path.Combine(baseDir, "configuration.xml");
var statusPath = Path.Combine(baseDir, "status.xml");
try {
string msg;
Console.WriteLine($"\nTrying to parse configuration file [{configPath}]...\n");
_config = ServiceConfig.Deserialize(configPath);
Console.WriteLine($"\nTrying to parse configuration files from [{baseDir}]...\n");
_config = ServiceConfig.Deserialize(baseDir);
msg = "------------------ configuration settings ------------------";
Console.WriteLine($"{msg}\n{_config.Summary()}{msg}\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment