Properties file based configuration mechanism for Parsley
In this post I introduce a new mechanism for Parsley to load part of a Context from a properties file. This way highly dynamic of changing properties can be managed externally from the properties file, avoiding the verbosity of an XML approach. As always, the source code is attached.
One of the things I like a lot about Parsley are all its extenstion points and available hooks to extends its native functionalities or default behaviours. In these regards a very useful extension point is, Tom explained a while ago, the different configuration mechanisms.
As explained in the documentation you can use a combined configuration mechanism to separate more dynamic or change-prone definitions from the more static ones. You could use an XML-based context defintion for the former and an MXML-based context definition for the latter.
While the XML-based context definition might work in most of the cases it might not be the best solution in some scenarios due to its verbosity.
Imagine I have an AIR2 based application which creates an HTTPServer instance. The server instance is created an managed by a Parsley Context:
type="{HTTPServerImpl}">
<spicefactory:ConstructorArgs>
<spicefactory:NestedObject type="{RequestProcessorFactory}"/>
<fx:Number>5000</fx:Number>
<fx:String>0.0.0.0</fx:String>
</spicefactory:ConstructorArgs>
</spicefactory:Object>
The second constructor parameter, 5000, is the port the server will be listening to and the third-one, 0.0.0.0, is the network interface where the server will be binded to.
These 2 parameters are potentially prone to change whereas the rest of the definition will be very static and rarely change. In my case these parameters should be configurable and maintained by IT administrators or even final users.
Moving this definition to a runtime configuration mechanism seems like the right thing. The main problem of moving this into an XML-based context is that it’d be too verbose and meaningless to the the targeted users who should maitain and drive the changes, thus making the configuration system of the application too weak and error-prone while exposing things that shouldn’t be changed (at least by these users).
What I would like to do is define in a more static way the server creation instance, making it safer to undesired configurations, but make more dynamic some of its arguments:
type="{HTTPServerImpl}">
<spicefactory:ConstructorArgs>
<spicefactory:NestedObject type="{RequestProcessorFactory}"/>
<spicefactory:ObjectRef idRef="port"/>
<spicefactory:ObjectRef idRef="host"/>
</spicefactory:ConstructorArgs>
</spicefactory:Object>
Then we could define the port and host parameters using any other mechanism.
My approach has been to create a properties file based configuation. I create config.properties like:
host=0.0.0.0
And then the following combined configuration mechanism:
<spicefactory:FlexConfig type="{ CommonConfiguration }"/>
<processor:PropertiesConfig file="data/config.properties"/>
</spicefactory:ContextBuilder>
This way the Parsley Context is built using an standard mxml approach together with a properties file based configuation. The PropertiesConfig implementation uses ContextBuilderProcessor and AsyncConfigurationProcessor extensions, load and parse the specified properties file and inject the property definitions into the context as simple strings. These definitions can then be used elsewhere normally.
You can find attached the entire implementation. Note that I implemented this against trunk (v.2.3.M1-snapshot) so it might not work out-of-the-box for other versions.
This technique could be used in a wide range of scenarios. You could define RemoteObjects and ChannelSet in an MXML compiled configuration file but inject from a properties file the url of the Channel. i.e.
<spicefactory:Property name="uri">
<spicefactory:ObjectRef idRef="amfChannelUri"/>
</spicefactory:Property>
</spicefactory:Object>
In the config.properties:
And the declare the ContextBuilder as:
<spicefactory:FlexConfig type="{ CommonConfiguration }"/>
<processor:PropertiesConfig file="data/config.properties"/>
</spicefactory:ContextBuilder>
Note, as suggested by Jens, that there might be scenarios where a tag like ObjectRef is not a good fit (like when using some of the built-in Flex tags like mx:RemoteObject). Being able to use a plain Flex binding on a simple MXML attribute might be a nice alternative to having “heavyweight” top-level String objects.
Other very intersting ways to achieve this same behaviour suggested by Jens (all kudos to him):
1. Use XML Configuration declaring strings like:
<constructor-args>
<string>0.0.0.0</string>
</constructor-args>
</object>
2. Create a custom tag that does the above in a more concise syntax using the Spicelib XML-Object-Mapper and a Parsley XMLConfigurationNamespace. You can see an example of this approach in Cairngorm3 Module library
3. Use the approach of an Environment class holding these values in the XML file, but use a custom
<spicefactory:NestedObject type="{RequestProcessorFactory}"/>
<custom:PropertyRef idRef="environment" property="port"/>
<custom:PropertyRef idRef="environment" property="host"/>
</spicefactory:ConstrunctorArgs>
The PropertyRef tag would require a bit of work (and it would be different for Parsley 2.2 and 2.3 due to some changes in internal APIs.
Download PropertiesConfig for Parsley..
2 Comments to “Properties file based configuration mechanism for Parsley”
Leave a Reply

Am I right in thinking that this stuff has been picked up by the Parsley people and included in the Parsley project itself?
http://www.spicefactory.org/parsley/docs/2.4/manual/config.php#properties
HI Mostafa, yes this was incorporated to Parsley a while agoo