| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Chapter 11. Compendium Services</title><link rel="stylesheet" href="css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="index.html" title="Eclipse Gemini Blueprint Reference Guide"><link rel="up" href="reference.html" title="Part II. Reference Documentation"><link rel="prev" href="bundles.html" title="Chapter 10. Working With Bundles"><link rel="next" href="testing.html" title="Chapter 12. Testing OSGi based Applications"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="compendium"></a>Chapter 11. Compendium Services</h2></div></div></div><p>The OSGi Service Platform Service Compendium specification defines a |
| number of additional services that may be supported by OSGi |
| implementations. Gemini Blueprint supports an additional |
| "compendium" namespace that provides integration with some of these services. |
| By convention, the prefix <code class="literal">osgix</code> is used for this |
| namespace:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>> |
| <<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns</span><span class="co"><img src="images/callouts/1.png" alt="(1)"></span><span class="hl-attribute">:bp</span>=<span class="hl-value">"http://www.osgi.org/xmlns/blueprint/v1.0.0"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">xmlns:context</span>=<span class="hl-value">"http://www.springframework.org/schema/context"</span> |
| <span class="hl-attribute">xmlns:util</span>=<span class="hl-value">"http://www.springframework.org/schema/util"</span> |
| <span class="hl-attribute">xmlns:task</span>=<span class="hl-value">"http://www.springframework.org/schema/task"</span> |
| <span class="hl-attribute">xmlns:compendium</span>=<span class="hl-value">"http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans |
| http://www.springframework.org/schema/beans/spring-beans-3.2.xsd |
| http://www.springframework.org/schema/util |
| http://www.springframework.org/schema/util/spring-util-3.2.xsd |
| http://www.springframework.org/schema/task |
| http://www.springframework.org/schema/task/spring-task-3.2.xsd |
| http://www.osgi.org/xmlns/blueprint/v1.0.0 |
| http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd |
| http://www.springframework.org/schema/context |
| http://www.springframework.org/schema/context/spring-context-3.2.xsd |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd"</span>> |
| |
| <<span class="hl-comment">!-- use the OSGi namespace elements directly --</span>> |
| <<span class="hl-tag">service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"simpleServiceOsgi"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"simpleService"</span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.xyz.MyService"</span> /> |
| |
| <<span class="hl-comment">!-- qualify compendium namespace elements --</span>> |
| <<span class="hl-tag">compendium:cm-properties</span> <span class="hl-attribute">id</span>=<span class="hl-value">"cm"</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"com.xyz.myapp"</span>/> |
| |
| <<span class="hl-tag">/beans:beans</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Compendium namespace declaration (bound to <code class="literal">osgix</code> prefix)</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Schema location (namespace URI)</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>XML schema to use for the compendium namespace</p></td></tr></table></div></div><p>At present this namespace provides support for the Configuration |
| Admin service. Support for other compendium services may be added in |
| future releases.</p><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="compendium:cm"></a>11.1. Configuration Admin</h2></div></div></div><p>One of the most important compendium services, is the <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.osgi.org/javadoc/r4v401/org/osgi/service/cm/package-summary.html" target="_top">Configuration Admin</a> |
| which, as a name implies, provides configuration to interested bundles through the OSGi service registry. Gemini Blueprint provides dedicated support |
| for Configuration Admin (CM), allowing consumption and injection of the configuration data in a declarative way.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="compendium:cm:props"></a>11.1.1. Exposing Configuration Admin Entries As <code class="classname">Properties</code></h3></div></div></div><p>In its simplest form, the CM can be seen as a configuration source, namely a <code class="classname">Dictionary</code> whose |
| keys are always <code class="classname">String</code>s. Gemini Blueprint can expose entries in the CM as a <code class="classname">Properties</code> object, |
| through the <code class="literal">cm-properties</code> element. A minimal declaration looks as follows:</p><pre class="programlisting"><<span class="hl-tag">osgix:cm-properties</span> <span class="hl-attribute">id</span>=<span class="hl-value">"ds.cfg"</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"data.source.office.1"</span>/></pre><p>The configuration above, exposes the properties available in the CM under <span class="emphasis"><em>data.source.office.1</em></span> entry as a bean named |
| <span class="emphasis"><em>ds.cfg</em></span>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The <code class="literal">persistent-id</code> attribute must refer to the |
| persistent-id of an OSGi <code class="interfacename">ManagedService</code>, it is a |
| configuration error to specify a factory persistent id referring to a |
| <code class="interfacename">ManagedServiceFactory</code>.</p></td></tr></table></div><p>Those familiar with Spring's |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/xsd-configuration.html#xsd-config-body-schemas-util" target="_top">util schema</a> will |
| find <code class="literal"><osgi:cm-properties/></code> element similar to <code class="literal"><util:properties/></code>.</p><p>It is possible to specify a default set of property values to be used in the event that the configuration dictionary does not contain |
| an entry for a given key. The declaration is similar to the <code class="literal">props</code> element inside the Spring beans namespace:</p><pre class="programlisting"><<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>> |
| <<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:bp</span>=<span class="hl-value">"http://www.osgi.org/xmlns/blueprint/v1.0.0"</span> |
| <span class="hl-attribute">xmlns:context</span>=<span class="hl-value">"http://www.springframework.org/schema/context"</span> |
| <span class="hl-attribute">xmlns:util</span>=<span class="hl-value">"http://www.springframework.org/schema/util"</span> |
| <span class="hl-attribute">xmlns:task</span>=<span class="hl-value">"http://www.springframework.org/schema/task"</span> |
| <span class="hl-attribute">xmlns:compendium</span>=<span class="hl-value">"http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"</span> |
| |
| <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans |
| http://www.springframework.org/schema/beans/spring-beans-3.2.xsd |
| http://www.springframework.org/schema/util |
| http://www.springframework.org/schema/util/spring-util-3.2.xsd |
| http://www.springframework.org/schema/task |
| http://www.springframework.org/schema/task/spring-task-3.2.xsd |
| http://www.osgi.org/xmlns/blueprint/v1.0.0 |
| http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd |
| http://www.springframework.org/schema/context |
| http://www.springframework.org/schema/context/spring-context-3.2.xsd |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd"</span>> |
| |
| <<span class="hl-tag">compendium:cm-properties</span> <span class="hl-attribute">id</span>=<span class="hl-value">"cfg.with.defaults"</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"data.source.office.2"</span>> |
| <<span class="hl-tag">beans:prop</span> <span class="hl-attribute">key</span>=<span class="hl-value">"host"</span>>localhost<<span class="hl-tag">/beans:prop</span>> |
| <<span class="hl-tag">beans:prop</span> <span class="hl-attribute">key</span>=<span class="hl-value">"port"</span>>3306<<span class="hl-tag">/beans:prop</span>> |
| <<span class="hl-tag">/compendium:cm-properties</span>> |
| |
| <<span class="hl-tag">/beans:beans</span>></pre><p>By default, the properties found in the Configuration Admin entry will override the local properties. Thus, for the previous example, if the |
| <code class="literal">data.source.office.2</code> configuration contains a <span class="emphasis"><em>host</em></span> entry, its value will override the locally defined |
| <code class="literal">localhost</code>. For cases where this behaviour is undesired, the attribute <code class="literal">local-override</code> |
| (default <code class="literal">false</code>) allows one to revert the merging algorithm, forcing the local properties to override the entries in the CM.</p><p>Since <code class="literal">cm-properties</code> exposes the CM entries as <code class="classname">Properties</code>, it can be used with Spring's <code class="classname"> |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html#beans-factory-placeholderconfigurer" target="_top">PropertyPlaceholderConfigurer</a></code> |
| and <code class="classname"><a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html#beans-factory-overrideconfigurer" target="_top">PropertyOverrideConfigurer</a></code> |
| to externalize and customize environment-specific properties:</p><pre class="programlisting"><<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>> |
| <<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:context</span>=<span class="hl-value">"http://www.springframework.org/schema/context"</span> |
| <span class="hl-attribute">xmlns:mvc</span>=<span class="hl-value">"http://www.springframework.org/schema/mvc"</span> |
| <span class="hl-attribute">xmlns:bp</span>=<span class="hl-value">"http://www.osgi.org/xmlns/blueprint/v1.0.0"</span> |
| <span class="hl-attribute">xmlns:compendium</span>=<span class="hl-value">"http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"</span> |
| <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans |
| http://www.springframework.org/schema/beans/spring-beans-4.2.xsd |
| http://www.osgi.org/xmlns/blueprint/v1.0.0 |
| http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd |
| http://www.springframework.org/schema/context |
| http://www.springframework.org/schema/context/spring-context-4.2.xsd |
| http://www.springframework.org/schema/mvc |
| http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd"</span>> |
| |
| <<span class="hl-comment">!-- Configuration Admin entry --</span>> |
| <<span class="hl-tag">compendium:cm-properties</span> <span class="hl-attribute">id</span>=<span class="hl-value">"cmProps"</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"com.xyz.myapp"</span>> |
| <<span class="hl-tag">prop</span> <span class="hl-attribute">key</span>=<span class="hl-value">"host"</span>>localhost<<span class="hl-tag">/prop</span>> |
| <<span class="hl-tag">/compendium:cm-properties</span>> |
| |
| <<span class="hl-comment">!-- placeholder configurer --</span>> |
| <<span class="hl-tag">context:property-placeholder</span> <span class="hl-attribute">properties-ref</span>=<span class="hl-value">"cmProps"</span> /> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"dataSource"</span> <span class="hl-attribute">...></span> |
| <span class="hl-attribute"><property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"host"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"${host}"</span>/> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"timeout"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"${timeout}"</span>/> |
| <<span class="hl-tag">/bean</span>> |
| |
| <<span class="hl-tag">/beans</span>></pre><p>An important aspect of <code class="literal">cm-properties</code> is does <span class="emphasis"><em>not</em></span> reflect |
| any that any subsequent changes made to the entry it represents, made through the Configuration Admin API. |
| That is, once resolved, the <code class="literal">cm-properties</code> content remains the same, regardless of any updates |
| made the to CM entry it represents.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="compendium:cm:managed-properties"></a>11.1.2. Managed Properties</h3></div></div></div><p>Based on a configuration admin entry, Gemini Blueprint can autowire by name, the properties of a given bean. To use this feature, define |
| a nested <code class="literal">managed-properties</code> inside the bean definition:</p><pre class="programlisting"><<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"managedComponent"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"MessageTank"</span>> |
| <<span class="hl-tag">osgix:managed-properties</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"com.xyz.messageservice"</span>/> |
| <<span class="hl-tag">/bean</span>></pre><p>For each key in the dictionary stored by Configuration Admin under the given persistent id, |
| if the bean type has a property with a matching name (following JavaBeans conventions), |
| then that component property will be dependency injected with the value stored in Configuration Admin under the key. |
| If the definition of <code class="classname">SomeClass</code> from the example above is as follows:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> MessageTank { |
| <span class="hl-keyword">private</span> <span class="hl-keyword">int</span> amount; |
| <span class="hl-keyword">public</span> <span class="hl-keyword">int</span> getAmount() { <span class="hl-keyword">return</span> <span class="hl-keyword">this</span>.amount; } |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setAmount(<span class="hl-keyword">int</span> amount) { <span class="hl-keyword">this</span>.amount = amount; } |
| }</pre><p>and the configuration dictionary stored under the pid <code class="literal">com.xyz.messageservice</code> contains an entry |
| <code class="literal">amount=200</code>, then the <code class="literal">setAmount</code> method will be invoked on the bean |
| instance during configuration, passing in the value <code class="literal">200</code>.</p><p>If a property value is defined both in the configuration dictionary stored in the Configuration Admin service and in a |
| property element declaration nested in the component element, then the value from Configuration Admin takes precedence:</p><pre class="programlisting"><<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"managedComponent"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"MessageTank"</span>> |
| <<span class="hl-tag">osgix:managed-properties</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"com.xyz.messageservice"</span>/> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"amount"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"100"</span>/> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"threshold"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"500"</span>/> |
| <<span class="hl-tag">/bean</span>></pre><p>Property values specified via property elements can therefore be treated as default values to be used if none is available through |
| Configuration Admin.</p><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Warning"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="images/admons/warning.png"></td><th align="left">Warning</th></tr><tr><td align="left" valign="top">Do not share the same <span class="emphasis"><em>persistent-id</em></span> (PID) between multiple bundles or definitions, as <span class="emphasis"><em>only one</em></span> |
| of them will receive notifications. <code class="literal">managed-properties</code> relies on <code class="literal">org.osgi.service.cm.ManagedService</code> |
| contract which mandates that each <code class="literal">ManagedService</code> instance must be identified with its own unique PID. |
| Please see the Configuration Admin spec, specifically section 104.3 and 104.5</td></tr></table></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="compendium:cm:managed-properties:update"></a>11.1.2.1. Configuration Admin Runtime Updates</h4></div></div></div><p>A powerful feature of Configuration Admin is the ability to update (or delete) entries at runtime. That is, the configuration data |
| stored in Configuration Admin may be updated after the bean has been created. By default, any post-creation updates will be ignored. However, |
| one can configure <code class="literal">managed-properties</code> element to receive configuration updates through the <code class="literal">autowire-on-update</code> |
| and <code class="literal">update-method</code> attributes.</p><p><code class="literal">update-method</code> specifies the bean method to invoke whenever an update occurs in the configuration data. |
| The update method must have one of the following signatures:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(Map properties) |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(Map<String,?> properties); <span class="hl-comment">// for Java 5</span></pre><p>If <code class="literal">autowire-on-update</code> is set to <code class="literal">true</code> (default is <code class="literal">false</code>) then the container will autowire the target bean everytime an update occurs. |
| If both <code class="literal">autowire-on-update</code> and <code class="literal">update-method</code> are specified then the autowiring process will take precedence. |
| For autowiring, the component class must provide setter methods for the component properties that it wishes to have updated. Consider the following class definitions:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> ContainerManagedBean { |
| <span class="hl-comment">// will be reinjected (since it has a setter)</span> |
| <span class="hl-keyword">private</span> Integer integer; |
| <span class="hl-comment">// will not be reinjected (no setter present)</span> |
| <span class="hl-keyword">private</span> Long waitTime; |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setInteger(Integer integer) { <span class="hl-keyword">this</span>.integer = integer; } |
| } |
| |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">class</span> SelfManagedBean { |
| |
| <span class="hl-comment">// update callback</span> |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> updateCallback(Map properties) { |
| System.out.println(<span class="hl-string">"Received properties "</span> + properties); |
| System.out.println(<span class="hl-string">"Props can be used as a Dictionary "</span> + (Dictionary) properties); |
| <span class="hl-comment">// do more work ... </span> |
| } |
| }</pre><p>and configuraton:</p><pre class="programlisting"><<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"containerManaged"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"ContainerManagedBean"</span>> |
| <<span class="hl-tag">osgix:managed-properties</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"labX"</span> <span class="hl-attribute">autowire-on-update</span>=<span class="hl-value">"true"</span>/> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"integer"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"23"</span>/> |
| <<span class="hl-tag">/bean</span>> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"beanManaged"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"SelfManagedBean"</span>> |
| <<span class="hl-tag">osgix:managed-properties</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"labY"</span> <span class="hl-attribute">update-method</span>=<span class="hl-value">"updateCallback"</span>/> |
| <<span class="hl-tag">/bean</span>></pre><p>Any updates made to the CM entry <code class="literal">labX</code> will be automatically reinjected on existing instances of |
| <code class="literal">containerManaged</code> bean while the <code class="literal">labY</code> updates will be passed to <code class="methodname">updateCallback</code> |
| method.</p><p>The update options are summarized in the table below:</p><div class="table"><a name="compendium-cm-managed-properties-options"></a><p class="title"><b>Table 11.1. Managed Properties Update Options</b></p><div class="table-contents"><table summary="Managed Properties Update Options" width="100%" border="1"><colgroup><col><col><col></colgroup><thead><tr><th><code class="literal">autowire-on-update</code></th><th><code class="literal">update-method</code></th><th>Behaviour</th></tr></thead><tbody><tr><td><code class="literal">true</code></td><td><span class="emphasis"><em>optional</em></span>, called after autowiring</td><td>Reinjects the bean properties, using the properties present in the update. The re-injection will be applied while locking (through |
| a <code class="literal">synchronized</code> instruction) the bean instance. If the locking or re-injection strategy is not suitable, consider using |
| the <code class="literal">update-method</code> only approach.</td></tr><tr><td><code class="literal">false</code> (default)</td><td><span class="emphasis"><em>optional</em></span></td><td>Invokes the <code class="literal">update-method</code> callback on the bean instance, passing the updated configuration (as a |
| <code class="interfacename">Map</code> object that can be safely cast to a <code class="classname">Dictionary</code> if needed). No locking is |
| performed.</td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="compendium:cm:managed-service-factories"></a>11.1.3. Managed Service Factories</h3></div></div></div><p>The Configuration Admin service supports a notion of a <span class="emphasis"><em>managed service factory</em></span>(see section 104.6 in the Compendium Specification). |
| A managed service factory is identified by a factory pid which allows <span class="emphasis"><em>multiple</em></span> <code class="interfacename">Configuration</code> objects |
| to be associated with the factory. <code class="interfacename">Configuration</code> objects associated with the factory can be added or removed at any point. |
| The main intent of a factory is to create an OSGi service for each configuration: adding a new <code class="interfacename">Configuration</code> entry results |
| in a new OSGi service being registered, removing a <code class="interfacename">Configuration</code>, unregisters the service. |
| Gemini Blueprint provides support for the <span class="emphasis"><em>managed service factory</em></span> concept through the <code class="literal">managed-service-factory</code> element. Once |
| defined, the configuration associated with the factory pid will automatically create (or remove) bean instances which will be registered (or unregistered) |
| in the OSGi space based on a <span class="emphasis"><em>template</em></span> bean definition and the CM configuration.</p><p>This might sound more complicated then it actually is, so let's look at a simplistic example:</p><div class="programlistingco"><pre class="programlisting"><osgix:managed-service-factory id=<span class="hl-string">"simple-msf"</span> |
| factory-pid=<span class="hl-string">"com.xyz.messageservice"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| auto-export=<span class="hl-string">"all-classes"</span>> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| |
| <bean <span class="hl-keyword">class</span>=<span class="hl-string">"com.xyz.MessageTank"</span>/> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| </osgix:managed-service-factory></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>factory persistent id (pid)</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Shortcut flag used to determine under what interfaces the OSGi service is published (more info below)</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>bean definition <span class="emphasis"><em>template</em></span>. For each detected configuration, a new service will be created using |
| the bean definition template.</p></td></tr></table></div></div><p>In its simplest form, the <code class="literal">managed-service-factory</code> requires the <span class="emphasis"><em>factory pid</em></span>, a <span class="emphasis"><em>bean definition</em></span> |
| used as a template and some information on how possible bean instances are published as services. Basically, the definition above instructs |
| Gemini Blueprint to monitor the given factory pid (through a dedicated <code class="interfacename">ManagedServiceFactory</code> implementation (see the Compendium Spec for |
| more info)) and for every <code class="interfacename">Configuration</code> object associated with the factory pid, to create a new, anonymous instance of |
| the nested bean declared and export that instance as an OSGi service. The lifecycle of these beans instances is tied to the lifecycle of the |
| associated <code class="interfacename">Configuration</code> objects. If a new configuration is added, a new bean is created and exported. |
| If a configuration object is deleted or disassociated from the factory pid then the corresponding bean instance is destroyed.</p><p>In many regards, <code class="literal">managed-service-factory</code> acts as a specialized service exporter, similar to the |
| <a href="service-registry.html#service-registry:export" title="9.1. Exporting A Spring Bean As An OSGi Service"><code class="literal">service</code></a> element but supporting the concept of |
| <a href="compendium.html#compendium:cm:managed-properties" title="11.1.2. Managed Properties">managed properties</a>. In fact, many of |
| <code class="literal">service</code>'s attributes that indicate how a bean is exported, are found in <code class="literal">managed-service-factory</code> (as you saw in the |
| previous example with <code class="literal">auto-export</code>) as are the <code class="literal">managed-properties</code> attributes.</p><p>The list of attributes can be found below:</p><div class="table"><a name="compendium-cm-msf-options"></a><p class="title"><b>Table 11.2. Managed Service Factory Options</b></p><div class="table-contents"><table summary="Managed Service Factory Options" width="100%" border="1"><colgroup><col><col><col><col><col><col></colgroup><thead><tr><th align="center">Name</th><th colspan="4" align="center">Values</th><th align="center">Description</th></tr></thead><tbody><tr><td align="center">interface</td><td colspan="4" align="center">fully qualified class name (such as <code class="classname">java.lang.Thread</code>)</td><td align="center">the fully qualified name of the class under which the object will be exported</td></tr><tr><td align="center">context-class-loader</td><td colspan="2" align="center">unmanaged</td><td colspan="2" align="center">service-provider</td><td align="center">Defines how the context class loader will be managed when an operation is invoked on the |
| exported service. The default value is <code class="literal">unmanaged</code> which means that no management of |
| the context class loader is attempted. A value of <code class="literal">service-provider</code> guarantees that |
| the context class loader will have visibility of all the resources on the class path of |
| bundle exporting the service.</td></tr><tr><td align="center">auto-export</td><td align="center">disabled <code class="literal">(default)</code></td><td align="center">interfaces</td><td align="center">class-hierarchy</td><td align="center">all-classes</td><td align="center">Enables Spring to automatically manage the set of service interfaces advertised for the |
| service. By default this facility is <code class="literal">disabled</code>. A value of <code class="literal">interfaces</code> advertises all |
| of the Java interfaces supported by the exported service. A value of <code class="literal">class-hierarchy</code> |
| advertises all the Java classes in the hierarchy of the exported service. A value of |
| <code class="literal">all-classes</code> advertises all Java interfaces and classes.</td></tr><tr><td align="center">autowire-on-update</td><td colspan="2" align="center">false <code class="literal">(default)</code></td><td colspan="2" align="center">true</td><td align="center">Whether or not the container should autowire the target bean everytime an update occurs. |
| When <code class="literal">true</code> is specified, the container will perform autowire (by name) the bean instance with the |
| newly set properties. In case <code class="literal">update-method</code> attribute is used as well, the autowiring process will |
| take precedence.</td></tr><tr><td align="center">update-method</td><td colspan="2" align="center">none <code class="literal">(default)</code></td><td colspan="2" align="center">someMethod</td><td align="center">The update method to invoke whenever an update occurs in the configuration data. Allows the target |
| bean to process the update information itself. In case <code class="literal">autowire-on-update</code> is also used, the <code class="literal">update-method</code> |
| will be invoked after the autowiring takes place.</td></tr></tbody></table></div></div><br class="table-break"><p>Similar to the <code class="literal">service</code> element, a list of interfaces or/and registration listeners can be declared to be notified when a |
| service is being registered/unregistered. For more information on the semantics, please see <a href="service-registry.html#service-registry:export:intfs" title="9.1.3. Controlling The Set Of Advertised Service Interfaces For An Exported Service">Section 9.1.3, “Controlling The Set Of Advertised Service Interfaces For |
| An Exported Service”</a> and |
| <a href="service-registry.html#service-registry:export:lifecycle" title="9.1.10. Service Registration And Unregistration Lifecycle">Section 9.1.10, “Service Registration And Unregistration Lifecycle”</a> chapters.</p><p>Now that the <code class="literal">managed-service-factory</code> options have been explained, let's look at a more complex configuration:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"queueTracker"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.xyz.queue.QueueTracker"</span>/> |
| |
| <<span class="hl-tag">osgix:managed-service-factory</span> <span class="hl-attribute">id</span>=<span class="hl-value">"data-msf"</span> |
| <span class="hl-attribute">factory-pid</span>=<span class="hl-value">"org.xyz.labX"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">autowire-on-update</span>=<span class="hl-value">"true"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="hl-attribute">update-method</span>=<span class="hl-value">"refresh"</span>> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <<span class="hl-tag">osgix:interfaces</span>> |
| <<span class="hl-tag">value</span>>java.util.Collection<<span class="hl-tag">/value</span>> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <<span class="hl-tag">value</span>>java.util.Queue<<span class="hl-tag">/value</span>> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <<span class="hl-tag">/osgix:interfaces</span>> |
| <<span class="hl-tag">osgix:registration-listener</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"queueTracker"</span> <span class="co"><img src="images/callouts/5.png" alt="(5)"></span> |
| <span class="hl-attribute">registration-method</span>=<span class="hl-value">"track"</span> <span class="co"><img src="images/callouts/6.png" alt="(6)"></span> |
| <span class="hl-attribute">unregistration-method</span>=<span class="hl-value">"untrack"</span>/> <span class="co"><img src="images/callouts/7.png" alt="(7)"></span> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.xyz.ResizableQueue"</span>> <span class="co"><img src="images/callouts/8.png" alt="(8)"></span> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"size"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"100"</span>/> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"concurrency"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"10"</span>/> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"fair"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"false"</span>/> |
| <<span class="hl-tag">/bean</span>> |
| <<span class="hl-tag">/osgix:managed-service-factory</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p><code class="interfacename">ManagedServiceFactory</code> factory persistent id</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>whether Gemini Blueprint should autowire the bean when a <code class="interfacename">Configuration</code> is updated</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>the method to invoke after autowiring</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>the interfaces under which the nested beans are published as OSGi services</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/5.png" alt="5" border="0"></td><td valign="top" align="left"><p>listener notified when a service (based on the CM <code class="interfacename">Configuration</code>) is registered/unregistered</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/6.png" alt="6" border="0"></td><td valign="top" align="left"><p>custom (optional) service registration method</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/7.png" alt="7" border="0"></td><td valign="top" align="left"><p>custom (optional) service unregistration method</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/8.png" alt="8" border="0"></td><td valign="top" align="left"><p>bean definition template</p></td></tr></table></div></div><p>The example above, creates a imaginary <code class="classname">ResizeableQueue</code> instance for each <code class="interfacename">Configuration</code> entry |
| present under the <code class="literal">org.xyz.labX</code> factory pid. Each instance has default values assigned to <code class="literal">size</code>, <code class="literal">concurrency</code> |
| and <code class="literal">fair</code> parameters. However, just like <code class="literal">managed-properties</code>, during the bean creation, the values received from the |
| Configuration Admin will be injected by name, possibly overriding existing settings. Once created and configured, each nested, anonymous bean instance |
| is registered as an OSGi service under the <code class="interfacename">java.util.Collection</code> and <code class="interfacename">java.util.Queue</code> |
| interfaces. The OSGi service lifecycle is monitored by a registration listener, namely the bean <code class="literal">queueTracker</code>. |
| Finally, due to the specified <code class="literal">autowire-on-update</code> and <code class="literal">update-method</code> attributes, any updates executed to each CM configuration |
| will cause the container to autowire the associated bean instance with the newly set properties and after that a |
| <code class="methodname">refresh</code> callback will be invoked on it.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="compendium:cm:dict"></a>11.1.4. Direct Access To Configuration Data</h3></div></div></div><p>The simplest way to work directly with the configuration data stored under a given persistent id or factory persistent id, |
| is to register a service that implements either the <code class="interfacename">ManagedService</code> or <code class="interfacename">ManagedServiceFactory</code> |
| interface and specify the pid that you are interested in as a service property (for more information, see the Configuration Admin chapter |
| in the OSGi compendium spec). For example:</p><pre class="programlisting"><<span class="hl-tag">osgi:service</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"org.osgi.service.cm.ManagedService"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"myManagedService"</span>> |
| <<span class="hl-tag">osgi:service-properties</span>> |
| <<span class="hl-tag">entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"service.pid"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"my.managed.service.pid"</span>/> |
| <<span class="hl-tag">/osgi:service-properties</span>> |
| <<span class="hl-tag">/osgi:service</span>> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myManagedService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.xyz.MyManagedService"</span>/></pre></div></div></div><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bundles.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="testing.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 10. Working With Bundles </td><td width="20%" align="center"><span style="color:white;font-size:90%;"><a href="http://www.SpringSource.com/" title="SpringSource - Spring from the Source">Sponsored by SpringSource |
| </a></span></td><td width="40%" align="right" valign="top"> Chapter 12. Testing OSGi based Applications</td></tr></table></div></body></html> |