blob: 0d3afac96289ea4b598bf330609b789eb386d236 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter&nbsp;11.&nbsp;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&nbsp;II.&nbsp;Reference Documentation"><link rel="prev" href="bundles.html" title="Chapter&nbsp;10.&nbsp;Working With Bundles"><link rel="next" href="testing.html" title="Chapter&nbsp;12.&nbsp;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&nbsp;11.&nbsp;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">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<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>&gt;
&lt;<span class="hl-comment">!-- use the OSGi namespace elements directly --</span>&gt;
&lt;<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> /&gt;
&lt;<span class="hl-comment">!-- qualify compendium namespace elements --</span>&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/beans:beans</span>&gt;</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.&nbsp;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.&nbsp;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">&lt;<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>/&gt;</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">&lt;osgi:cm-properties/&gt;</code> element similar to <code class="literal">&lt;util:properties/&gt;</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">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<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>&gt;
&lt;<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>&gt;
&lt;<span class="hl-tag">beans:prop</span> <span class="hl-attribute">key</span>=<span class="hl-value">"host"</span>&gt;localhost&lt;<span class="hl-tag">/beans:prop</span>&gt;
&lt;<span class="hl-tag">beans:prop</span> <span class="hl-attribute">key</span>=<span class="hl-value">"port"</span>&gt;3306&lt;<span class="hl-tag">/beans:prop</span>&gt;
&lt;<span class="hl-tag">/compendium:cm-properties</span>&gt;
&lt;<span class="hl-tag">/beans:beans</span>&gt;</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">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<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>&gt;
&lt;<span class="hl-comment">!-- Configuration Admin entry --</span>&gt;
&lt;<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>&gt;
&lt;<span class="hl-tag">prop</span> <span class="hl-attribute">key</span>=<span class="hl-value">"host"</span>&gt;localhost&lt;<span class="hl-tag">/prop</span>&gt;
&lt;<span class="hl-tag">/compendium:cm-properties</span>&gt;
&lt;<span class="hl-comment">!-- placeholder configurer --</span>&gt;
&lt;<span class="hl-tag">context:property-placeholder</span> <span class="hl-attribute">properties-ref</span>=<span class="hl-value">"cmProps"</span> /&gt;
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"dataSource"</span> <span class="hl-attribute">...&gt;</span>
<span class="hl-attribute">&lt;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>/&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
&lt;<span class="hl-tag">/beans</span>&gt;</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.&nbsp;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">&lt;<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>&gt;
&lt;<span class="hl-tag">osgix:managed-properties</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"com.xyz.messageservice"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</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">&lt;<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>&gt;
&lt;<span class="hl-tag">osgix:managed-properties</span> <span class="hl-attribute">persistent-id</span>=<span class="hl-value">"com.xyz.messageservice"</span>/&gt;
&lt;<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>/&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</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.&nbsp;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&lt;String,?&gt; 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">&lt;<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>&gt;
&lt;<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>/&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
&lt;<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>&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</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&nbsp;11.1.&nbsp;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.&nbsp;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">&lt;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>&gt; <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
&lt;bean <span class="hl-keyword">class</span>=<span class="hl-string">"com.xyz.MessageTank"</span>/&gt; <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
&lt;/osgix:managed-service-factory&gt;</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.&nbsp;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.&nbsp;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&nbsp;11.2.&nbsp;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.&nbsp;Controlling The Set Of Advertised Service Interfaces For An Exported Service">Section&nbsp;9.1.3, &#8220;Controlling The Set Of Advertised Service Interfaces For
An Exported Service&#8221;</a> and
<a href="service-registry.html#service-registry:export:lifecycle" title="9.1.10.&nbsp;Service Registration And Unregistration Lifecycle">Section&nbsp;9.1.10, &#8220;Service Registration And Unregistration Lifecycle&#8221;</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">&lt;<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>/&gt;
&lt;<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>&gt; <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
&lt;<span class="hl-tag">osgix:interfaces</span>&gt;
&lt;<span class="hl-tag">value</span>&gt;java.util.Collection&lt;<span class="hl-tag">/value</span>&gt; <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
&lt;<span class="hl-tag">value</span>&gt;java.util.Queue&lt;<span class="hl-tag">/value</span>&gt; <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
&lt;<span class="hl-tag">/osgix:interfaces</span>&gt;
&lt;<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>/&gt; <span class="co"><img src="images/callouts/7.png" alt="(7)"></span>
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.xyz.ResizableQueue"</span>&gt; <span class="co"><img src="images/callouts/8.png" alt="(8)"></span>
&lt;<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>/&gt;
&lt;<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>/&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
&lt;<span class="hl-tag">/osgix:managed-service-factory</span>&gt;</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.&nbsp;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">&lt;<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>&gt;
&lt;<span class="hl-tag">osgi:service-properties</span>&gt;
&lt;<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>/&gt;
&lt;<span class="hl-tag">/osgi:service-properties</span>&gt;
&lt;<span class="hl-tag">/osgi:service</span>&gt;
&lt;<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>/&gt;</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>&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="testing.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;10.&nbsp;Working With Bundles&nbsp;</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">&nbsp;Chapter&nbsp;12.&nbsp;Testing OSGi based Applications</td></tr></table></div></body></html>