This is the continuation of
- Sling OSGi Track pt 1: hand-rolled service bundle and
- Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries and
- Sling OSGi Track pt 3: replacing the Activator with DS
- Sling OSGi Track pt 4: installing to Sling using Maven
- Sling OSGi Track pt 5: Bundling initial content
- Sling OSGI Track pt 6: Sling Servlets I
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:
- CRX quickstart
- Bundle Plugin for Maven
- SCR Plugin for Maven
- Maven Sling Plugin
- Felix' Configuration Admin Service implementation
Files:
- https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7.jar
- https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7-sources.jar
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:
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".
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.
No comments:
Post a Comment