4.4 Creating and Using Configuration Artifacts

Applications typically include some sort of configuration data that might change depending on the environment in which the application is deployed. For example, if an application connects to a database server using JDBC, the configuration data would include the JDBC URL of the database server, the JDBC drvier, and the username and password that the application uses to connect to the database server. This information often changes as the application is deployed to different computers or the application moves from the testing phase to the production phase.

Virgo provides a feature called configuration artifacts that makes it very easy for you to manage this configuration data. A configuration artifact is simply a properties file that is made available at runtime using the OSGi ConfigurationAdmin service. When you create this properties file, you set the values of the properties for the specific environment in which you are going to deploy your application, and then update the metadata of your Spring application to use the properties file. You then deploy the application and properties file together, typically as a plan . Virgo automatically creates a configuration artifact from the properties file, and you can manage the lifecycle of this configuration artifact in the same way you manage the lifecycle of PARs, bundles, and plans, using the Admin Console. Additionally, Virgo subscribes your application for notification of any refresh of the configuration artifact and the application can then adapt accordingly, which means you can easily change the configuration of your application without redeploying it.

In sum, configuration artifacts, especially when combined with plans, provide an excellent mechanism for managing external configuration data for your applications.

The following sections describe the format of the configuration artifact, how to update the Spring application context file of your application so that it knows about the configuration artifact, and finally how to include it in a plan alongside your application.

As an example to illustrate the configuration artifact feature, assume that you have a Spring bean called PropertiesController whose constructor requires that four property values be passed to it, as shown in the following snippet of Java code:

@Controller
public class PropertiesController {

    private final String driverClassName;
    private final String url;
    private final String username;
    private final String password;

    public PropertiesController(String driverClassName, String url, String username, String password) {
        this.driverClassName = driverClassName;
        this.url = url;
        this.username = username;
        this.password = password;
}

In the preceding example, the PropertiesController constructor requires four property values: driverClassName, url, username, and password. Note that the example shows just one way that a class might require property values; your application may code it another way.

Additionally, assume that the following snippet of the associated Spring application context XML file shows how the PropertiesController bean is configured:

<bean class="com.springsource.configuration.properties.PropertiesController">
                <constructor-arg value="${driverClassName}"/>
                <constructor-arg value="${url}"/>
                <constructor-arg value="${username}"/>
                <constructor-arg value="${password}"/>
</bean>

The rest of this section describes how the bean can get these property values using a configuration artifact.

Creating the Properties File

To create a properties file that in turn will become a configuration artifact when deployed to Virgo from which a Spring bean, such as the PropertiesController bean, will get the actual property values, follow these guidelines:

  • Create a text file in which each property is listed as a name/value pair, one pair per line. Precede comments with a #. For example:

    # Properties for the com.springsource.configuration.properties sample
    
    driverClassName   = org.w3.Driver
    url               = http://www.springsource.com
    username          = joe
    password          = secret

    The example shows four properties whose name correspond to the constructor arguments of the PropertiesController Spring bean.

  • Name the file anything you want, as long as it has a .properties extension, such as app-properties.properties.

Updating Your Application

To update your application so that it "knows" about the configuration artifact, you update the application's Spring application context XML file, typically located in the WEB-INF or META-INF/spring directories (read Using Spring and Spring DM to understand which directory to use).

You use the <context:property-placeholder> element to specify that you want to use the Virgo mechanism for substituting values into bean properties. The properties-ref attribute of this element points to a <osgi-compendium:cm-properties> element which you use to specify the configuration artifact that contains the property values. You set the value of the persistent-id attribute of this element equal to the name of the configuration artifact, which is the name of the properties file minus the .properties extension.

The following sample Spring application context XMl file shows everything wired together; only relevant parts of the file are shown:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium"
  xsi:schemaLocation="http://www.springframework.org/schema/osgi 
    http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/osgi-compendium 
    http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium-1.2.xsd">

...

        <bean class="com.springsource.configuration.properties.PropertiesController">
                <constructor-arg value="${driverClassName}"/>
                <constructor-arg value="${url}"/>
                <constructor-arg value="${username}"/>
                <constructor-arg value="${password}"/>
        </bean>

        <context:property-placeholder properties-ref="configAdminProperties"/>

        <osgi-compendium:cm-properties id="configAdminProperties" persistent-id="app-properties"/>

...

</beans> 

The preceding example shows how the id configAdminProperites wires the <context:property-placeholder> and <osgi-compendium:cm-properties> elements together. Based on the value of the persistent-id attribute, you must also deploy a properties file called app-properties.properties which Virgo installs as a configuration artifact.

Adding the Configuration Artifact to a Plan

Although you can always deploy your application and associated configuration artifact using the pickup directory, we recommends that you group the two together in a plan, add the two artifacts to the repository, and then deploy the plan using the pickup directory. The following sample plan includes the two artifacts:

<?xml version="1.0" encoding="UTF-8"?>
<plan name="multi-artifact.plan" version="1.0.0" 
         scoped="false" atomic="false"
        xmlns="http://www.eclipse.org/virgo/schema/plan"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="
		        http://www.eclipse.org/virgo/schema/plan
		        http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd">

    <artifact type="configuration" name="app-properties" version="0"/>
    <artifact type="bundle" name="org.eclipse.virgo.configuration.properties" version="1.0.0"/>
</plan>

For additional information about plans, see Creating Plans.