Fork me on GitHub

n. Slang a rough lawless young Kuali developer.
[perhaps variant of Houlihan, Irish surname]
kualiganism n

Blog of an rSmart Java Developer. Full of code examples, solutions, best practices, et al.

Wednesday, May 23, 2012

Low-carb KFS Configuration

Overview

Currently, KFS is configured at build time. This is rough on deployment because build machines must know about the machine being deployed to. This couples build and deployment together. Rough, right? We all miss the days when you could change a config file entry, and it would modify the service, right? One example that comes to might immediately is Rice. If you typo your datasource url, you just fix your rice-config.xml and restart. Now you're cooking with gas. Unfortunately, KFS will give you no such love...or will it?

I recently stumbled on some code in the PropertyLoadingFactoryBean that suggests it was intended to work this way from the beginning. I want to go over just a few lines of code and a way to manage properties to make this a pretty seamless transition.

PropertyLoadingFactoryBean

This is the class from KFS 4.1.1



You can see that riceXmlConfigurer.getProperties() gets called just after creating riceXmlConfigurer. If you have a look at the rice 1.0.3.3 JAXBConfigImpl, you will see that the constructor just initializes a fileLocs ArrayList. The properties never get initialized or parsed. Basically, this code that looks like it's supposed to load rice configuration data actually does nothing.

The question now becomes, "How do we get it to work?" The magic method call that is missing is, parseConfig. Here's what I did to fix it:



You can see where I call parseConfig with the try/catch, but there is this other section where I am loading more configs. I figured that while I was in here, I'd make a few refinements. Rice already makes use of a property called "additional.config.locations". Since Rice is using it, I figure it must be fair-game in all kuali applications. I just make use of it here. "additional.config.locations" is a property that supplies a comma-delimited list of configuration files. They are then loaded into the configuration. Awesome, right?!

From .properties to .xml

Now that we've found a more flexible way, how are we going to switch over?

Setup Defaults

The PropertyLoadingFactoryBean showed us that classpath:META-INF/common-config-defaults.xml is already being read. It is located in META-INF which actually in work/src. Later, this will end up in kfs-${environment}/WEB-INF/classes/META-INF. What I end up putting in it is:



These files are counterparts to the .properties files in build/properties. I converted each of the .properties to .xml using this line of shell code:



Even comes tied up with a pretty little bow.

kfs-config.xml

You may recall from the commons-config-defaults.xml that I defined ${user.home}/kuali/main/${environment}/kfs-config.xml as an "additional.config.location". This is where I will add my environment-specific configuration information. Here's an example:



What about configuration.properties and security.properties?

What I did is I emptied these files so that they are not used. They still get built and used, but they are deprecated.

That's it

Relatively easy. If you're still using ant builds, there are some caveats. If you can, I highly recommend switching to maven.



No comments:

Post a Comment