Combining configuration files - apache-commons

I'm developing a jee application which has to look at two files in order to load configuration parameters. Both files are properties-like files.
The first one contains a default configuration properties and the other one overrides them. So the first one is read-only and the other one can be modified. I need to react and update changes made on second configuration file.
I've take a look on several resources:
Composite Configuration
Combined Configuration
Combining Configuration Sources
I've not been able to figure out what and how to make configuration strategy with commons-configuration2.
Up to now, I've been able to read from one configuration file:
FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
new FileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class)
.configure(new Parameters().properties()
.setFileName(ConfigurationResources.PROPERTIES_FILEPATH)
.setThrowExceptionOnMissing(true)
.setListDelimiterHandler(new DefaultListDelimiterHandler(';'))
.setIncludesAllowed(false));
Any ideas?

You need CombinedConfiguration. Here is the sample code
Parameters params = new Parameters();
CombinedConfigurationBuilder builder = new CombinedConfigurationBuilder()
.configure(params.fileBased().setFile(new File("configuration.xml")));
CombinedConfiguration cc = builder.getConfiguration();
Here configuration.xml file would contain the list of property files
<configuration systemProperties="systemProperties.xml">
<!-- Load the system properties -->
<system/>
<!-- Now load the config file, using a system property as file name -->
<properties fileName="myprops1.properties"/>
<properties fileName="myprops2.propert"/>
</configuration>
This documentation on Combined Configuration will be really helpful

Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> config1 = new FileBasedConfigurationBuilder<FileBasedConfiguration>(
PropertiesConfiguration.class)
.configure(params.properties().setFileNamesetFileName("file1.properties")));
FileBasedConfigurationBuilder<FileBasedConfiguration> config2 = new FileBasedConfigurationBuilder<FileBasedConfiguration>(
PropertiesConfiguration.class).configure(params.properties().setFileName("default_file2.properties"));
CombinedConfiguration config = new CombinedConfiguration(new OverrideCombiner());
config.addConfiguration(config1.getConfiguration());//this overrides config2
config.addConfiguration(config2.getConfiguration());
return config;
This is something I have used in my project to create a combined configuration. A combined configuration naturally creates a hierarchy of configurations taken from different or same source. For example you could also write something like : FileBasedConfigurationBuilder<FileBasedConfiguration> config2 = new FileBasedConfigurationBuilder<FileBasedConfiguration>( PropertiesConfiguration.class).configure(params.properties()‌​.setFileName(System.‌​getProperty("default‌​_file2.properties"))‌​);
The FileBasedConfigurationBuilder can be substituted with any kind of configuration you may like. Refer to the link https://commons.apache.org/proper/commons-configuration/apidocs/org/apache/commons/configuration2/builder/BasicConfigurationBuilder.html

Related

Azure Cloud Service - different mapping per environment

I have a Cloud Service in Azure and I have multiple environments.
One of my classes use a mapping (key-value mapping) for doing some calculations.
The number of keys in that mapping varies depending on the environment.
I'm guessing I have no choice but to insert (somehow) the mapping to the environment's configuration (.cscfg file).
Since the configuration is in XML format, I'm wondering what would be the cleanest and most extensible way for define the mapping for each of the environments.
Thanks
For example:
I have this ID to Region mapper:
private static readonly Dictionary<string, Region> Id = new Dictionary<string, Region>
{
{"1", Region.UsE},
{"2", Region.UsE},
{"3", Region.UsE},
{"4", Region.UsSC},
{"5", Region.UsSC},
{"6", Region.UsSC},
{"7", Region.EuW},
{"8", Region.EuN}
};
This mapping changes between environments and I would like somehow to elegantly set the mapping in the cscfg file of each environment.
Hope this better explains my question.
You can add the values to the ConfigurationSettings element of the .CSCFG files for each environment. The values may then be read using the CloudConfigurationManager class.
You could also just have per-environment XML or JSON files.

How to build a file based on defined-type instances in Puppet

I want my Puppet class to create a file resource with contents based on all instances of a particular defined type. I looked at this question with the idea of iterating over the instances to build the file, but apparently it's a "Bad Idea" per the one answer currently there.
Some background: I am building a monitor_service class in Puppet to deploy a custom monitoring application. The application reads a config file that tells it what to monitor, one item per line, along the lines of
ITEM: /var/things/thing-one (123)
ITEM: /var/things/thing-two (456)
I am also writing a defined type that deploys instances of the monitored items:
define my_thing::monitored_thing ( $port ) {
file { "/var/things/$name":
...
}
}
On a given node, I set up several monitored_things like
my_thing::monitored_thing { "thing-one":
port => 123
}
my_thing::monitored_thing { "thing-two":
port => 456
}
What's the "right" Puppet idiom for building the monitoring service config file? I would prefer for this to work in such a way that the monitor_service class doesn't have to be told which monitored_thing instances it is watching -- just creating a monitored_thing instance should cause it to be added to the config file automatically.
There are several ways to modify/declare only part of a file within multiple defined types:
Use puppetlabs-stdlib's file_line. This lets you specify that a file should contain a specific line. Best when you do not care about the other file contents and just want to make sure a line is present or absent.
Use puppetlabs-concat if you want to make sure that the final file only includes the fragments that you are specifying or the order of the fragments matters.
Use the augeas type if you need to edit/add configuration to a file with a more complicated structure, like xml, apache configurations, etc.

How to create predictable logging locations with sbt-native-packager

I am using sbt-native-packager with the experimental Java Server archetype. I am trying to identify a conventional way to access my log files, and I'm wondering if anyone knows of a common approach here. Since I am using the Java Server archetype, I am getting a symlink /var/log/$app -> install_dir/$app/log, but it feels a little dirty and less portable to just have log4j open /var/log/$app/error.log directly.
[Update]
I ended up creating an object with run time path information:
object MakaraPaths {
def getLogPath = new File(getJarPath, "../logs").getPath
def getConfigPath = new File(getJarPath, "../conf").getPath
def getJarPath = {
val regex = new Regex("(/.+/)*")
val jarPath = Makara.getClass.getProtectionDomain.getCodeSource.getLocation.getPath
(regex findAllIn jarPath).mkString("")
}
}
In my main method, I established a system property based on the new MakaraPaths object:
System.setProperty("logPath", MakaraPaths.getLogPath)
I also used this for my config file:
val config = ConfigFactory.parseFile(new File(MakaraPaths.getConfigPath, "application.conf"))
Ultimately, to load the log file, I used a System Property lookup:
<RollingFile name="fileAppender" fileName="${sys:logPath}/server.log" filePattern="${sys:logPath}/server_%d{yyMMdd}.log">
This gets me most of the way where I needed to be. It's not completely portable, but it does technically support my use case. (Deploying to Ubuntu)
You could use relative path in log4j configuration. Just write logs in logs/filename.log.
During installation symlink install_dir/$app/logs -> /var/log/$app will be created, and all logs will be written in /var/log/$app/filename.log

move the reference to working directory using libgit2sharp

I want to change the reference to the working directory to a different place using LibGit2Sharp in a Visual C++ project. it seems to me that Repository::Init() with RepositoryOptions can set the working directory to a non-default place. What I am trying to do here, however, is to change the reference to the working directory for the repo AFTER it is created by Repository::Init(). Repository::Info::WorkingDirectory seems to a be read-only property, so I can't change it through this route.
Any thoughts on how to accomplish this? or the equivalent of git_repository_set_workdir() is not exposed in LibGit2Sharp.
What I am trying to do here, however, is to change the reference to the working directory for the repo AFTER it is created by Repository::Init().
Repository.Init() puts a folder under source control by creating a new repository on the filesystem. It returns an instance of the created repository.
The constructor of the Repository type gives you acces to an existing repository. This constructor accepts an optional RepositoryOptions parameter to override some options.
In order to fulfill your request I'd go with something like this
var path ="D:\path\to\your\repo";
using (var repo = Repository.Init(path)
{
// Do nothing here
}
var newWorkdir ="D:\path\to\your\other\working\directory";
var options = new RepositoryOptions { WorkingDirectoryPath = newWorkdir };
using (var repo = new Repository(path, options))
{
// Do YOUR amzing stuff ;-)
}
Update:
The config file of the repo does not have the worktree attribute set to the right place, and the new working directory does not have a .git file pointing to the repo folder, as what you would expect.
This is the expected behavior. Passing a RepositoryOptions type to the constructor temporarily overrides some settings of the Repository. Once the repo is disposed, those temporary settings are lost.
I check the libgit2sharp source code for repository.cs and happen to notice that when it calls git_repository_set_workdir, it only has two arguments, as opposed to three
The bound libgit2 method is invoked with three params, the third one being set to false, because we do not want to persist the temporary settings when instanciating a repository.
Back to your original question: "What I am trying to do here, however, is to change the reference to the working directory for the repo AFTER it is created by Repository::Init()."
This is currently not possible with LibGit2Sharp. However, it might be possible to make this happen DURING the call to Repository.Init() through the addition of an optional parameter. If this looks like something may fit your need, I'd suggest you to open an issue regarding this topic, or even better, send a Pull Request ;-)
Another option would be for you to manually set the core.worktree config variable to the expected location (You'd have to deal with the creation of the gitlink by yourself, though):
The code below demonstrates this last option:
var path ="D:\path\to\your\repo";
// Note the use of forward slashes here
var newWorkdir ="D:/path/to/your/other/working/directory";
using (var repo = Repository.Init(path)
{
repo.Config.Set("core.worktree", newWorkdir);
}
using (var repo = new Repository(path))
{
// Do YOUR amzing stuff ;-)
}
Update 2:
LibGit2Sharp has just been updated with PR #453.
Among other things, this makes repo.Init() accept a separate git directory, which should fit your requirements.

requirejs config with arbitrary data

In an Dojo 1.7 AMD web app you can define also arbitrary data in the config object (http://dojotoolkit.org/reference-guide/loader/amd.html).
The configuration object can also be used to set arbitrary, application-specific configuration data. All properties of a configuration object are shallow copied to require.rawConfig
I looked to the requirejs config page (http://requirejs.org/docs/api.html#config), but I did not find a similar feature here. But I did not look into the source code.
Is there a possibility to store arbitrary infos in the requirejs config and get access to it?
Thanks alot in advance
Wolfgang
As far as I can see it is not supported.
You need to insert 1 line in the require.js source code to get this feature.
Here is an example:
require.config({
test: "one",
paths: {
'jquery': 'libs/jquery/1.7.1/jquery',
...
Along with the normal values you store your arbitrary information.
Then, you have to open the requirejs source code with a text editor.
Approximately in line 380 - 390 (depends on your version), function "makeRequire":
This function calls another called "mixin":
mixin(modRequire, {
nameToUrl: makeContextModuleFunc(context.nameToUrl, relModuleMap),
toUrl: makeContextModuleFunc(context.toUrl, relModuleMap),
defined: makeContextModuleFunc(context.requireDefined, relModuleMap),
specified: makeContextModuleFunc(context.requireSpecified, relModuleMap),
isBrowser: req.isBrowser,
rawConfig: config
});
After "isBrowser" write "rawConfig: config".
Now, in your amd module:
define(['require'], function (require){
alert (require.rawConfig.test);
...
Update:
This feature will be implimented in requirejs 1.1.
https://github.com/jrburke/requirejs/issues/182

Resources