258 lines
15 KiB
HTML
258 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
|
||
|
||
|
||
|
||
<!--<link rel="shortcut icon" href="https://www.openhab.org/favicon.png"></link>-->
|
||
<title>Event Admin - openHAB 2 - Empowering the Smart Home</title>
|
||
|
||
<!-- CSS -->
|
||
<link type="text/css" rel="stylesheet" href="/v2.2/css/materialize.css" media="screen,projection" />
|
||
<link type="text/css" rel="stylesheet" href="/v2.2/css/pygments-jekyll-style.css" />
|
||
<link type="text/css" rel="stylesheet" href="/v2.2/css/styles.css" />
|
||
<link type="text/css" rel="stylesheet" href="/v2.2/css/openhab.css" />
|
||
<link type="text/css" rel="stylesheet" href="/v2.2/css/collapsible.css" />
|
||
|
||
<!-- Font -->
|
||
<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
||
<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400,700" />
|
||
<link rel="canonical" href="https://docs.openhab.org/developers/prerequisites/eventadmin.html" />
|
||
<script type="text/javascript">var gaProperty = 'UA-47717934-3';var disableStr = 'ga-disable-' + gaProperty;if (document.cookie.indexOf(disableStr + '=true') > -1) {window[disableStr] = true;}</script>
|
||
<script>
|
||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||
ga('create', 'UA-47717934-3', 'auto');
|
||
ga('set', 'anonymizeIp', true);
|
||
ga('send', 'pageview');
|
||
</script>
|
||
</head>
|
||
|
||
|
||
<body class="documentation">
|
||
<div id="header" class="navbar-fixed">
|
||
<nav role="navigation">
|
||
<div class="container">
|
||
<div class="nav-wrapper">
|
||
<a href="/v2.2/index.html"><img id="logo" src="/images/logo.png" /></a>
|
||
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
|
||
<ul class="right hide-on-med-and-down">
|
||
<li><a href="/tutorials/index.html">Tutorials</a></li>
|
||
<li><a href="/v2.2/introduction.html">User Manual</a></li>
|
||
<li><a href="/developers/index.html">Developer Guide</a></li>
|
||
<li><a target="_blank" href="https://community.openhab.org">Community Forum</a></li>
|
||
<li><a target="_blank" href="https://github.com/openhab">GitHub</a></li>
|
||
<li class="search"><i class="material-icons">search</i></li>
|
||
<li class="search">
|
||
<form method="GET" id="searchform" class="search-form" action="/search">
|
||
<input id="query" name="q" type="text" class="search-form-input" placeholder="search" />
|
||
</form>
|
||
</li>
|
||
</ul>
|
||
<ul id="nav-mobile" class="side-nav">
|
||
<li><a href="/v2.2/index.html">Home</a></li>
|
||
<li><a href="/tutorials/index.html">Tutorials</a></li>
|
||
<li><a href="/v2.2/introduction.html">User Manual</a></li>
|
||
<li><a href="/developers/index.html">Developer Guide</a></li>
|
||
<li><a target="_blank" href="https://community.openhab.org">Community Forum</a></li>
|
||
<li><a target="_blank" href="https://github.com/openhab">GitHub</a></li>
|
||
<li class="search">
|
||
<form method="GET" id="searchformmob" class="search-form" action="/search">
|
||
<input id="querymob" name="q" type="text" class="search-form-input" placeholder="search" />
|
||
</form>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
|
||
|
||
<section id="documentation" class="text content-wrapper">
|
||
<div class="container">
|
||
<div class="side-nav-wrapper">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<ul class="nav">
|
||
<li><a href="/v2.2/developers">Overview</a></li>
|
||
<li><a href="/v2.2/developers/contributing/contributing">Contributing</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/osgi.html">Prerequisites</a>
|
||
<ul>
|
||
<li><a href="/v2.2/developers/prerequisites/osgi.html">OSGi</a>
|
||
<ul>
|
||
<li><a href="/v2.2/developers/prerequisites/osgi.html">Overview</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/osgids.html">Declarative Services</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/configadmin.html">Configuration Admin</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/osgitasks.html">Coding tasks</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/eventadmin.html">Event Admin</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="/v2.2/developers/prerequisites/tycho.html">Tycho</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/equinox.html">Equinox</a></li>
|
||
<li><a href="/v2.2/developers/prerequisites/targetplatform.html">Target Platform</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="/v2.2/developers/development/ide.html">Basics</a>
|
||
<ul>
|
||
<li><a href="/v2.2/developers/development/ide.html">IDE Setup</a></li>
|
||
<li><a href="/v2.2/developers/development/guidelines.html">Code Guidelines</a></li>
|
||
<li><a href="/v2.2/developers/development/bindings.html">Developing Bindings</a></li>
|
||
<li><a href="/v2.2/developers/development/logging.html">Logging</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="/v2.2/developers/development/evolution.html">Migration from 1.x</a>
|
||
<ul>
|
||
<li><a href="/v2.2/developers/development/evolution.html">Technical Differences</a></li>
|
||
<li><a href="/v2.2/developers/development/compatibilitylayer.html">Compatibility Layer</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div class="content">
|
||
|
||
<h1 id="event-admin-service">Event Admin Service</h1>
|
||
|
||
<h2 id="introduction">Introduction</h2>
|
||
|
||
<p>In a dynamic environment like OSGi, communication with events has a wide variety of use cases. A lot of core services share information using events, so understanding how to use events in OSGi is fundamental.</p>
|
||
|
||
<h2 id="basics">Basics</h2>
|
||
|
||
<h3 id="publish-subscribe-pattern">Publish-Subscribe Pattern</h3>
|
||
|
||
<p>OSGi events are based on the publish-subscribe messaging pattern. Let’s use the definition for the pattern that can be found in the <a href="https://osgi.org/download/r4v42/r4.cmpn.pdf">OSGi Compendium Specification</a> : <em>This pattern decouples sources from their handlers by interposing an event channel between them. The publisher posts events to the channel, which identifies which handlers need to be notified and then takes care of the notification process.</em></p>
|
||
|
||
<p>What is interesting about the OSGi model is that both publishers and subscribers can disappear at any time. A central module to track the handlers availability is needed - the <em>Event Admin Service</em>.</p>
|
||
|
||
<h3 id="event-admin-service-1">Event Admin Service</h3>
|
||
|
||
<p>The <em>Event Admin Service</em> (<code class="highlighter-rouge">org.osgi.service.event.EventAdmin</code>) takes a central place in the communication between <em>Event Publishers</em> and subscribers (<em>Event Listeners</em>). It is responsible for keeping track of the listeners, and sending events to them. It supports both synchronous and asynchronous sending that will be reviewed in more details in the <a href="#send-events">section about sending events</a>. But let’s illustrate that with the following picture:</p>
|
||
|
||
<p><img src="images/event-admin.png" alt="Bundle lifecycle" /></p>
|
||
|
||
<p>Fig.1 Event Admin Service (Source: <a href="http://enroute.osgi.org/img/services/org.osgi.service.event.overview.png">http://enroute.osgi.org/img/services/org.osgi.service.event.overview.png</a>)</p>
|
||
|
||
<p>Before going into more details, let’s take a look at the events.</p>
|
||
|
||
<h3 id="event">Event</h3>
|
||
|
||
<p>The <em>Event</em> interface(<code class="highlighter-rouge">org.osgi.service.event.Event</code>) encapsulates a single message. It contains:</p>
|
||
|
||
<ul>
|
||
<li>topic - used from the <em>Event Admin Service</em> as a filter to dispatch the events only to the listeners that are interested;</li>
|
||
<li>payload - the information that we would like to send. It is represented by a key-value pair.</li>
|
||
</ul>
|
||
|
||
<h2 id="receive-events">Receive Events</h2>
|
||
|
||
<p>In order to receive an event through the <em>Event Admin Service</em> we have to register a service that implements the <code class="highlighter-rouge">org.osgi.service.event.EventHandler</code> interface with a property <em>event.topics</em> that contains all topics that we are interested in. An example with Declarative Service:</p>
|
||
|
||
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><scr:component</span> <span class="na">name=</span><span class="s">"com.example.handler"</span> <span class="na">xmlns:scr=</span><span class="s">"http://www.osgi.org/xmlns/scr/v1.1.0"</span><span class="nt">></span>
|
||
<span class="nt"><implementation</span> <span class="na">class=</span><span class="s">"com.example.LogEventHandler"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"event.topics"</span> <span class="na">type=</span><span class="s">"String"</span> <span class="na">value=</span><span class="s">"some/topic"</span><span class="nt">/></span>
|
||
<span class="nt"><service></span>
|
||
<span class="nt"><provide</span> <span class="na">interface=</span><span class="s">"org.osgi.service.event.EventHandler"</span><span class="nt">/></span>
|
||
<span class="nt"></service></span>
|
||
<span class="nt"><reference</span> <span class="na">cardinality=</span><span class="s">"1..1"</span> <span class="na">interface=</span><span class="s">"org.osgi.service.log.LogService"</span> <span class="na">name=</span><span class="s">"LogService"</span> <span class="na">policy=</span><span class="s">"static"</span><span class="nt">/></span>
|
||
<span class="nt"></scr:component></span>
|
||
</code></pre></div></div>
|
||
|
||
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">handler</span><span class="o">;</span>
|
||
|
||
<span class="kn">import</span> <span class="nn">org.osgi.service.event.Event</span><span class="o">;</span>
|
||
<span class="kn">import</span> <span class="nn">org.osgi.service.event.EventHandler</span><span class="o">;</span>
|
||
<span class="kn">import</span> <span class="nn">org.osgi.service.log.LogService</span><span class="o">;</span>
|
||
|
||
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">LogEventHandler</span> <span class="kd">implements</span> <span class="n">EventHandler</span> <span class="o">{</span>
|
||
|
||
<span class="kd">private</span> <span class="n">LogService</span> <span class="n">logService</span><span class="o">;</span>
|
||
|
||
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">bind</span><span class="o">(</span><span class="n">LogService</span> <span class="n">logService</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="k">this</span><span class="o">.</span><span class="na">logService</span> <span class="o">=</span> <span class="n">logService</span><span class="o">;</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">handleEvent</span><span class="o">(</span><span class="n">Event</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="n">logService</span><span class="o">.</span><span class="na">log</span><span class="o">(</span><span class="n">LogService</span><span class="o">.</span><span class="na">LOG_DEBUG</span><span class="o">,</span> <span class="s">" Recevied event with topic: "</span> <span class="o">+</span> <span class="n">event</span><span class="o">.</span><span class="na">getTopic</span><span class="o">());</span>
|
||
|
||
<span class="o">}</span>
|
||
|
||
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">undbind</span><span class="o">(</span><span class="n">LogService</span> <span class="n">logService</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="k">this</span><span class="o">.</span><span class="na">logService</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
|
||
<span class="o">}</span>
|
||
<span class="o">}</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>You can register a handler for multiple topics by adding the topics to the <em>event.topics</em> property (<code class="highlighter-rouge"><property name="event.topics" type="String" value="some/topic,other/topic"/></code>) or by using wildcard symbol (<code class="highlighter-rouge"><property name="event.topics" type="String" value="some/topic/*"/></code>).</p>
|
||
|
||
<h2 id="send-events">Send Events</h2>
|
||
|
||
<p>As we have already mentioned, you will need an <em>Event Admin Service</em> implementation to send events. In Equinox the service is implemented in the <code class="highlighter-rouge">org.eclipse.equinox.event</code> bundle. The service contains two methods for sending events:</p>
|
||
|
||
<ul>
|
||
<li><code class="highlighter-rouge">void postEvent(Event event)</code> - sends an Event asynchronously;</li>
|
||
<li><code class="highlighter-rouge">void sendEvent(Event event)</code> - sends an Event synchronously;</li>
|
||
</ul>
|
||
|
||
<h2 id="further-reading">Further Reading</h2>
|
||
|
||
<ul>
|
||
<li><a href="https://osgi.org/download/r4v42/r4.cmpn.pdf"><em>OSGi Service Platform Service Compendium, Release 4, Version 4.2,August 2009</em></a></li>
|
||
<li><a href="http://enroute.osgi.org/services/org.osgi.service.event.html">http://enroute.osgi.org/services/org.osgi.service.event.html</a></li>
|
||
<li><a href="http://blog.vogella.com/2017/05/16/osgi-event-admin-publish-subscribe/">http://blog.vogella.com/2017/05/16/osgi-event-admin-publish-subscribe/</a></li>
|
||
</ul>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<footer>
|
||
<div class="container">
|
||
<div class="row">
|
||
<div class="col s12 m7">
|
||
Copyright © 2017 by the <a href="https://github.com/openhab">openHAB Community</a> and the <a href="http://www.openhabfoundation.org/">openHAB Foundation e.V.</a>
|
||
</div>
|
||
<div class="col s12 m5">
|
||
<ul class="list-inline right-align">
|
||
<li><a href="/imprint.html">Imprint</a></li>
|
||
<li><a href="/privacy.html">Privacy Policy</a></li>
|
||
<li><a href="http://www.openhab.org">openHAB Website</a></li>
|
||
<li><a href=# onclick="printPage()">Print This Page</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
<script src="/v2.2/js/jquery.min.js"></script>
|
||
<script src="/v2.2/js/jquery.scrollme.min.js"></script>
|
||
<script src="/v2.2/js/jquery.sticky.js"></script>
|
||
<script src="/v2.2/js/materialize.min.js"></script>
|
||
<script src="/v2.2/js/init.js"></script>
|
||
<script src="/v2.2/js/functions.js"></script>
|
||
</body>
|
||
</html>
|
||
|
||
<script>
|
||
var host = "docs.openhab.org";
|
||
if (!(window.location.host.startsWith("127.0.0.1")) && (host == window.location.host) && (window.location.protocol != "https:"))
|
||
window.location.protocol = "https";
|
||
</script>
|
||
|