Tuesday, September 9, 2008

Sling OSGi Track pt 7: configuring services at runtime

This is the continuation of

In this part, I will explain how to use the OSGi configuration management to configure services at runtime.

Suppose I want a service that can do more than just say "hello". I want the phrase the service returns from the sayHello() method to be configurable at runtime. This is easily done through OSGi configuration management.

Aims:

  • Show how to introduce a configurable property into an OSGi bundle
  • Show how to change the configuration through the OSGi configuration manager

Ingredients:

Files:

Outline:

  • Project Structure
  • Changes to the implementation
  • The pom
  • The results
  • Testing

Execution

Project Structure

From here on, I am no longer bundling the sample client script, as we've done our own client servlet in part 6 of this track. So we're back to just the pom, the interface and the implementation.

.
|-- pom.xml
`-- src
    `-- main
        `-- java
            `-- mh
                `-- osgitest
                    |-- SampleService.java
                    `-- SampleServiceImpl.java
Changes to the implementation

The only semantic change is in lines 18 and 21: a property helloPhrase is introduced and the value that is returned from the "sayHello()" method is read from that property.

Lines 11-14 introduce a constant, PROP_HELLO_PHRASE. The value of that constant will be used as a key to store the actual value. Line 12 points to the DEFAULT_HELLO_PHRASE constant for the default value. The following would have been equivalent, but it's better practice to use constants, so that the default value can be reffered to from Java code.

	/**
	 * @scr.property value="hello"
	 */
	public static final String PROP_HELLO_PHRASE = "mh.osgitest.helloPhrase";

the activate() method is called when the component is activated. At that point, we can obtain configuration values from the properties that are part of the ComponentContext that is passed as the method's argument.

package mh.osgitest;

import org.osgi.service.component.ComponentContext;

/**
 * @scr.component immediate="true"
 * @scr.service interface="SampleService"
 */
public class SampleServiceImpl implements SampleService {

	/**
	 * @scr.property valueRef="DEFAULT_HELLO_PHRASE"
	 */
	public static final String PROP_HELLO_PHRASE = "mh.osgitest.helloPhrase";

	public static final String DEFAULT_HELLO_PHRASE = "hello";

	private String helloPhrase;

	public String sayHello() {
		return helloPhrase;
	}

	protected void activate(ComponentContext context) {
		Object helloPhrase = context.getProperties().get(PROP_HELLO_PHRASE);
		if (helloPhrase != null)
			this.helloPhrase = helloPhrase.toString();
	}
}
The pom

The pom is very straight forward. Nothing special here.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>mh.studies</groupId>
	<artifactId>mh.studies.sling.osgitest</artifactId>
	<name>OSGI Test Bundle</name>
	<version>0.0.7</version>
	<packaging>bundle</packaging>
	<description />
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.sling</groupId>
				<artifactId>maven-sling-plugin</artifactId>
				<version>2.0.2-incubator</version>
				<executions>
					<execution>
						<id>install-bundle</id>
						<goals>
							<goal>install</goal>
						</goals>
						<configuration>
							<slingUrl> http://localhost:7402/system/console/install</slingUrl>
							<user>admin</user>
							<password>admin</password>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
			    <groupId>org.apache.felix</groupId>
			    <artifactId>maven-scr-plugin</artifactId>
			    <version>1.0.7</version>
			    <executions>
			        <execution>
			            <id>generate-scr-scrdescriptor</id>
			            <goals>
			                <goal>scr</goal>
			            </goals>
			        </execution>
			    </executions>
			</plugin>			
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<version>1.4.3</version>
				<extensions>true</extensions>
				<configuration>
					<instructions>
						<Export-Package>mh.osgitest</Export-Package>
						<Import-Package>
                            org.osgi.framework;version="1.3.0",
                            org.osgi.service.component
                        </Import-Package>
						<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
						<Bundle-Name>${pom.name}</Bundle-Name>
						<Bundle-Vendor>Moritz Havelock</Bundle-Vendor>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>apache.incubating</id>
			<name>Apache Incubating Repository</name>
			<url>http://people.apache.org/repo/m2-incubating-repository</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>apache.incubating.plugins</id>
			<name>Apache Incubating Plugin Repository</name>
			<url>http://people.apache.org/repo/m2-incubating-repository
			</url>
		</pluginRepository>
	</pluginRepositories>
	<dependencies>
		<dependency>
			<groupId>org.apache.felix</groupId>
			<artifactId>org.osgi.core</artifactId>
			<version>1.0.1</version>
		</dependency>
            <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.osgi.compendium</artifactId>
            <version>1.0.1</version>
        </dependency>
	</dependencies>
</project>
The results

After deploying the Bundle, I do a quick test and call http://localhost:7402/system/osgitest/info. That requires that the Servlet from the last part is still installed. If you have not followed along, grab it from here: http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-6-sling-servlets-i.html.

As expected, I get the result "hello".

Now, I hit the OSGi configuration management console at http://localhost:7402/system/console/configMgr and select my bundle from the drop down:

snap002 2008-09-09

Don't be confused by the naming of the entries. They can easily be replaced, but I will keep focused on the important stuff for a while and leave these out of consideration.

I get the following screen, which allows me to configure the component's properties. In our case, that is the "helloPhrase" property, which I can change by entering a new value into the text box and hitting "save".

snap003 2008-09-09

 

Testing

The final test is to again hit http://localhost:7402/system/osgitest/info, which should now return the new value of the "helloPhrase" property.

Technorati Tags: ,,

No comments: