felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > Apache Felix Event Admin
Date Tue, 23 Feb 2010 16:46:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Event+Admin">Apache
Felix Event Admin</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~cziegeler@apache.org">Carsten
Ziegeler</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h1><a name="ApacheFelixEventAdmin-ApacheFelixEventAdmin"></a>Apache
Felix Event Admin</h1>

<p>The Event Admin Service Specification, part of the OSGi Compendium specification,
defines a general inter-bundle communication mechanism. The communication conforms to the
popular publish/subscribe paradigm and can be performed in a synchronous or asysnchronous
manner.</p>

<p>The main components in a publish/subscribe communication are:</p>

<ul>
	<li><b>Event Publisher</b> - sends events or messages related to a specific
<b>topic</b></li>
	<li><b>Event Handler</b> (or <b>Subscriber</b>) - expresses
interest in one or more topics and receives all the messages belonging to such topics.</li>
</ul>


<p>Events are composed of two attributes:</p>

<ul>
	<li>a <b>topic</b> defining the nature of the event; topic names are usually
arranged in a hierarchical namespace, where slashes are used to separate the levels (i.e.
"org/osgi/framework/FrameworkEvent/STARTED") and</li>
	<li>a set of <b>properties</b> describing the event.</li>
</ul>


<h2><a name="ApacheFelixEventAdmin-CreatinganEventPublisher"></a>Creating
an Event Publisher</h2>

<p>An event publisher is a simple Java class that creates events and sends them using
the <tt>EventAdmin</tt> service interface, for example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    <span class="code-keyword">public</span> void reportGenerated(Report report,
BundleContext context)
    {
        ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
        <span class="code-keyword">if</span> (ref != <span class="code-keyword">null</span>)
        {
            EventAdmin eventAdmin = (EventAdmin) context.getService(ref);
            
            Dictionary properties = <span class="code-keyword">new</span> Hashtable();
            properties.put(<span class="code-quote">"title"</span>, report.getTitle());
            properties.put(<span class="code-quote">"path"</span> , report.getAbsolutePath());
            properties.put(<span class="code-quote">"time"</span>, <span class="code-object">System</span>.currentTimeMillis());
            
            Event reportGeneratedEvent = <span class="code-keyword">new</span>
Event(<span class="code-quote">"com/acme/reportgenerator/GENERATED"</span>, properties);
            
            eventAdmin.sendEvent(reportGeneratedEvent);
        }
    }
</pre>
</div></div>

<p>The <tt>EventAdmin.sendEvent()</tt> method sends the <tt>Event</tt>
object synchronously. To send it asynchronously, use the <tt>EventAdmin.postEvent()</tt>
method, such as:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
            <span class="code-comment">//..		
</span>            Event reportGeneratedEvent = <span class="code-keyword">new</span>
Event(<span class="code-quote">"com/acme/reportgenerator/GENERATED"</span>, properties);
            eventAdmin.postEvent(reportGeneratedEvent);
</pre>
</div></div>

<h2><a name="ApacheFelixEventAdmin-CreatinganEventHandler"></a>Creating
an Event Handler</h2>

<p>Creating an event handler is as simple as implementing the <tt>EventHandler</tt>
interface:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class ReportEventHandler <span class="code-keyword">implements</span>
EventHandler
{
    <span class="code-keyword">public</span> void handleEvent(Event event)
    {
        <span class="code-object">String</span> reportTitle = (<span class="code-object">String</span>)
event.getProperty(<span class="code-quote">"title"</span>);
        <span class="code-object">String</span> reportPath = (<span class="code-object">String</span>)
event.getProperty(<span class="code-quote">"path"</span>);
        
        sendReportByEmail(reportTitle, reportPath);
    }
    
    <span class="code-comment">//..</span>
</pre>
</div></div>

<h2><a name="ApacheFelixEventAdmin-RegisteringanEventHandler"></a>Registering
an Event Handler</h2>

<p>To receive event notifications, the event handler must be registered as a OSGi service
under the object class <tt>org.osgi.service.event.EventHandler</tt>. When registering
the service, a <tt>String[]</tt> property named <tt><b>EVENT_TOPIC</b></tt>
must be specified; this property describes the list of topics in which the event handler is
interested. For example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        <span class="code-object">String</span>[] topics = <span class="code-keyword">new</span>
<span class="code-object">String</span>[] {
            <span class="code-quote">"com/acme/reportgenerator/GENERATED"</span>
        };
        
        Dictionary props = <span class="code-keyword">new</span> Hashtable();
        props.put(EventConstants.EVENT_TOPIC, topics);
        bundleContext.registerService(EventHandler.class.getName(), <span class="code-keyword">new</span>
ReportEventHandler() , props);
</pre>
</div></div>

<p>It is possible to use '*' as a wildcard in the final character of the EVENT_TOPIC,
like in this example:</p>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        <span class="code-object">String</span>[] topics = <span class="code-keyword">new</span>
<span class="code-object">String</span>[] {
            <span class="code-quote">"com/acme/reportgenerator/*"</span>
        };
        
        Dictionary props = <span class="code-keyword">new</span> Hashtable();
        props.put(EventConstants.EVENT_TOPIC, topics);
        bundleContext.registerService(EventHandler.class.getName(), <span class="code-keyword">new</span>
ReportEventHandler() , props);
</pre>
</div></div>

<p>Finally, it is possible to specify an additional <tt>EVENT_FILTER</tt>
property to filter event notifications; the filter expression follows, the normal LDAP syntax:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        <span class="code-object">String</span>[] topics = <span class="code-keyword">new</span>
<span class="code-object">String</span>[] {
            <span class="code-quote">"com/acme/reportgenerator/GENERATED"</span>
        };
        
        Dictionary props = <span class="code-keyword">new</span> Hashtable();
        props.put(EventConstants.EVENT_TOPIC, topics);
        props.put(EventConstants.EVENT_FILTER, <span class="code-quote">"(title=samplereport)"</span>);
        bundleContext.registerService(EventHandler.class.getName(), <span class="code-keyword">new</span>
ReportEventHandler() , props);
</pre>
</div></div>

<h2><a name="ApacheFelixEventAdmin-OSGiEvents"></a>OSGi Events</h2>

<p>Every OSGi framework sends (asynchronously) a number of events that can be captured
by any bundle.</p>

<h3><a name="ApacheFelixEventAdmin-FrameworkEvents"></a>Framework Events</h3>

<ul>
	<li>org/osgi/framework/BundleEvent/STARTED</li>
	<li>org/osgi/framework/BundleEvent/ERROR</li>
	<li>org/osgi/framework/BundleEvent/PACKAGES_REFRESHED</li>
	<li>org/osgi/framework/BundleEvent/STARTLEVEL_CHANGED</li>
	<li>org/osgi/framework/BundleEvent/WARNING</li>
	<li>org/osgi/framework/BundleEvent/INFO</li>
</ul>


<h3><a name="ApacheFelixEventAdmin-BundleEvents"></a>Bundle Events</h3>

<ul>
	<li>org/osgi/framework/BundleEvent/INSTALLED</li>
	<li>org/osgi/framework/BundleEvent/STARTED</li>
	<li>org/osgi/framework/BundleEvent/STOPPED</li>
	<li>org/osgi/framework/BundleEvent/UPDATED</li>
	<li>org/osgi/framework/BundleEvent/UNINSTALLED</li>
	<li>org/osgi/framework/BundleEvent/RESOLVED</li>
	<li>org/osgi/framework/BundleEvent/UNRESOLVED</li>
</ul>


<p>The followig properties are always present in a bundle event object:</p>

<ul>
	<li><b>bundle.id</b></li>
	<li><b>bundle.symbolicName</b></li>
</ul>


<h3><a name="ApacheFelixEventAdmin-ServiceEvents"></a>Service Events</h3>

<ul>
	<li>org/osgi/framework/ServiceEvent/REGISTERED</li>
	<li>org/osgi/framework/ServiceEvent/MODIFIED</li>
	<li>org/osgi/framework/ServiceEvent/UNREGISTERING</li>
</ul>


<p>The following properties are always present in a service event object:</p>

<ul>
	<li><b>service</b></li>
	<li><b>service.id</b></li>
	<li><b>service.pid</b></li>
</ul>


<p>Each of the aforementioned events actually contains a wider set of properties. Check
the OSGi Compendium specification, section 113.6, for a complete list.</p>

<h2><a name="ApacheFelixEventAdmin-Configuration"></a>Configuration</h2>

<p>The Apache Felix Event Admin implementation is trying the deliver the events as fast
as possible. Events sent from different threads are sent in parallel. Events from the same
thread are sent in the order they are received (this is according to the spec).<br/>
A timeout can be configured which is used for event handlers. If an event handler takes longer
than the configured timeout to process an event, it is blacklisted. Once a handler is in a
blacklist, it doesn't get sent any events anymore.<br/>
The Felix Event Admin can be configured either through framework properties or through the
configuration admin. This is a list of configuration properties:</p>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'>Function</th>
<th class='confluenceTh'>Property Name</th>
<th class='confluenceTh'>Type and Default</th>
<th class='confluenceTh'>Description</th>
</tr>
<tr>
<td class='confluenceTd'>Cache Size</td>
<td class='confluenceTd'>org.apache.felix.eventadmin.CacheSize</td>
<td class='confluenceTd'>Integer, 30</td>
<td class='confluenceTd'>The size of various internal caches. The default value is 30.
Increase in case of a large number (more then 100) of services. A value less then 10 triggers
the default value.</td>
</tr>
<tr>
<td class='confluenceTd'>Thread Pool Size</td>
<td class='confluenceTd'>org.apache.felix.eventadmin.ThreadPoolSize</td>
<td class='confluenceTd'>Integer, 10</td>
<td class='confluenceTd'>The size of the thread pool. The default value is 10. Increase
in case of a large amount of synchronous events where the event handler services in turn send
new synchronous events in the event dispatching thread or a lot of timeouts are to be expected.
A value of less then 2 triggers the default value. A value of 2 effectively disables thread
pooling.</td>
</tr>
<tr>
<td class='confluenceTd'>Timeout</td>
<td class='confluenceTd'>org.apache.felix.eventadmin.Timeout</td>
<td class='confluenceTd'>Integer, 5000</td>
<td class='confluenceTd'>The black-listing timeout in milliseconds. The default value
is 5000. Increase or decrease at own discretion. A value of less then 100 turns timeouts off.
Any other value is the time in milliseconds granted to each event handler before it gets blacklisted.</td>
</tr>
<tr>
<td class='confluenceTd'>Require Topic</td>
<td class='confluenceTd'>org.apache.felix.eventadmin.RequireTopic</td>
<td class='confluenceTd'>Boolean, true</td>
<td class='confluenceTd'>Are event handlers required to be registered with a topic?
This is enabled by default. The specification says that event handlers must register with
a list of topics they are interested in. Disabling this setting will enable that handlers
without a topic are receiving all events (i.e., they are treated the same as with a topic=*).</td>
</tr>
<tr>
<td class='confluenceTd'>Ignore Timeouts</td>
<td class='confluenceTd'>org.apache.felix.eventadmin.IgnoreTimeout</td>
<td class='confluenceTd'>String, empty</td>
<td class='confluenceTd'>Configure event handlers to be called without a timeout. If
a timeout is configured by default all event handlers are called using the timeout. For performance
optimization it is possible to configure event handlers where the timeout handling is not
used - this reduces the thread usage from the thread pools as the timout handling requires
an additional thread to call the event handler. However, the application should work without
this configuration property. It is a pure optimization! The value is a list of strings. If
a string ends with a dot, all handlers in exactly this package are ignored. If the string
ends with a star, all handlers in this package and all subpackages are ignored. If the string
neither ends with a dot nor with a start, this is assumed to define an exact class name.</td>
</tr>
</tbody></table>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Event+Admin">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=120268&revisedVersion=3&originalVersion=2">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Event+Admin?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message