Saturday, December 12, 2009

OSGi -Spring - Configuration Admin - Dynamic Property file changes

Normally we have been reading the property files ourselves or used spring property-holder feature or even cm-properties. In all these cases update to the property file are not visible.

You can now use the managed-properties under Configuration Admin and have the values updated in your bean automatically whenever you change the property file. You just drop a property file inside pickup directory and under the bean definition specify the persistent-id as follows:


// Have a property file with name myPropertyFile
<osgix:cm-properties id="config" persistent-id="myPropertyFile"/>

//declare a property place holder config with id of osgi:cm
<context:property-placeholder properties-ref="config"/>

//bean definition using teh property file
<bean id="configTest" class="com.test.ConfigTest">
<osgix:managed-properties persistent-id="myPropertyFile" update-strategy="container-managed" /> <property name="propertyValue" value="${propertyValue}"></property>
</bean>

Now first add the property file to the pick up folder and start the DM server. The setPropertyValue() setter will be called and the value will be initialized when application bundle is dropped.

[There are multiple calls to this setter because of the osgi configuration admin]

Now when the property file in changed in the pickup directory , the setter method will be called and new value will be set into the bean.

Incase you want to manage the updates yourself you can change the update-strategy and provide the update-method in the bean. In this case all the key/values are provided to the method in form of a Map.

<bean id="configTest" class="com.test.ConfigTest">
<osgix:managed-properties persistent-id="myPropertyFile"
update-strategy="bean-managed" update-method="refresh" />
<property name="propertyValue" value="${propertyValue}"></property>
</bean>

The ConfigTest class is as follows

public class ConfigTest {

private int propertyValue;

public void setPropertyValue(int propertyValue) {

System.out.println("setter called for property"+propertyValue);
this.propertyValue = propertyValue;
}


public void refresh(Map <String,String> keyVals)
{
System.out.println("referhs called with value"+keyVals);
}

}

PS:

Do not share the same persistent-id (PID) between multiple bundles or definitions, as only one of them will receive notifications. managed-properties relies on org.osgi.service.cm.ManagedService contract which mandates that each ManagedService instance must be identified with its own unique PID.

Hence the best option in a service model is to have a configuration service reading the property file and giving notifications to required bundles.

No comments:

 
Free Domain Names @ .co.nr!