Eventing systems are a common part of software programs, used to distribute information between parts of an application. To address this, the Event Admin Service Specification was created as one of the earliest specifications defined by the OSGi Compendium. The design and usage of the Event Admin specification, however, makes certain trade-offs that do not fit well with modern application design:
-
Type Safety - Events are sent and received as opaque maps of key-value pairs. The “schema” of an event is therefore ill-defined and relies on “magic strings” being used correctly to locate data, and on careful handling of data values with unknown types.
-
Unhandled Events - Events that are sent but have no interested Event Consumers are silently discarded. There is no way to know that an event was not handled, short of disrupting the system by registering a handler for all events.
-
Observability - There is no simple, non-invasive way to monitor the flow of events through the system. The ability to monitor and profile applications using Event Admin is therefore relatively limited.
Adding these features to the original Event Admin Service Specification specification is not feasible without breaking backward compatibility for clients. Therefore this specification exists to provide an alternative eventing model which supports these different requirements by making different design trade-offs.
-
Event - A set of data created by an Event Source, encapsulated as an object and delivered to one or more Event Consumers.
-
Event Schema - A definition of the expected data layout within an event, including the names of data fields and the types of data that they contain.
-
Event Topic - A String identifying the topic of an Event, effectively defining the Event Schema and the purpose of the event.
-
Event Source - A software component which creates and sends events.
-
Event Consumer - A software component which receives events.
-
DTO - A Data Transfer Object as per the OSGi DTO Specification.
-
Event Bus - A software component used by an Event Source and responsible for delivering Events to Event Consumers.
-
Typed Event Bus - A service registered by the Typed Event implementation that can be passed an Event object and that will distribute that event to any suitable Event Handler Services.
-
Event Handler - A service registered by an Event Consumer suitable for receiving Event data from the Typed Event Bus.
In this specification an Event is a set of string keys associated with data values. The defined set of allowable keys and permitted value types for the keys in an Event is known as the Event Schema. Both the Event Source and Event Consumers must agree on a schema, or set of compatible schemas, in order for events to be consumed correctly.
A Type Safe Event is one in which the Event Schema is defined as a Java class. Using a Java class provides a formal definition of the schema - event data uses field names in the class as the keys, and each field definition defines the permitted type of the value.
Type Safe Event classes are expected to conform to OSGi DTO rules. The architecture of OSGi DTOs is described in OSGi Core Release 8. All methods, all static fields, and any non public instance fields of an event object must be ignored by the Typed Event Service when processing the Event data.
Some implementations of the Typed Event Service may support Type Safe Event classes that do not conform to the DTO rules, transforming them as needed in an implementation specific way. This is permitted by this specification, however consumers which rely on this behaviour may not be portable between different implementations of this specification.
OSGi DTOs are permitted to have data values which are also DTOs, allowing nested data structures to be created. This is also allowed for Type Safe Events, but with the same restriction that the event data must be a tree. There is no restriction on the depth of nesting permitted.
An Untyped Event is one in which there is no Java class defining
the Event Schema. In this case the event data is defined using a
Map
type with String
keys and values limited
to types acceptable as fields in a DTO, excepting:
-
DTO types - an untyped event may not have DTOs inside it as these form part of a typed schema.
-
Maps are only permitted if they follow the rules for Untyped events, that is having
String
keys and DTO restricted value types excluding DTOs.
Untyped Event instances are capable of representing exactly the same data as present in a Type Safe Event instance, and are also subject to the same restrictions, that is the data must be a tree. Nested data should be included as sub-maps within the event map, and these sub-maps may in turn contain nested data.
Some Event schemas may be represented by an existing type which does not match the OSGi DTO rules. In this case there are two main options:
-
Create a DTO representation of the event schema, and convert from the existing type into the DTO representation in code.
-
Convert the event data into an Untyped Event representation using nested Maps.
For example, the following code demonstrates how an object following the JavaBeans pattern can be converted into a DTO type or an untyped map:
public class ExampleJavaBean {
private String message;
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}
public class ExampleEvent {
public String message;
}
@Component
public class ExampleEventSource {
private ExampleEvent createEventFromJavaBean(ExampleJavaBean bean) {
return Converters.standardConverter().convert(bean)
.to(ExampleEvent.class);
}
private Map<String, Object> createMapFromJavaBean(ExampleJavaBean bean) {
return Converters.standardConverter().convert(bean)
.to(new TypeReference<Map<String, Object>>(){});
}
}
The Typed Event Service is inherently multi-threaded. Events may
be published from multiple threads, and event data may be delivered to
consumers on multiple threads. Event Sources and Event Consumers must
therefore assume that event data is shared between threads from the
moment that it is first passed to the TypedEventBus
.
Typed Events, and in particular DTO types, provide a simple yet powerful mechanism for defining an Event Schema in a type-safe way. However their use of mutable public fields means that they are potentially dangerous when shared between threads. Event Sources and Event Consumers should assume that their event instances are shared between threads and therefore not mutate the event data after publication or receipt.
If an Event Handler does need to make changes to an incoming event then it must copy the event data into a new DTO instance. Note that any nested DTO values in the event data must also be copied if they are to be mutated.
When an event source publishes untyped event data, it passes a Map instance to the Typed Event Bus. The Typed Event Bus is not required to take a copy of this Map, and therefore the event source must not change the Map, or any data structures within the Map, after the call to deliverUntyped(String,Map).
Untyped Events are delivered as implementations of the Map interface. Bundles consuming untyped events should not rely on the event object being any particular implementation of Map, and should treat the event object as immutable. The Typed Event Bus implementation may make copies of the event data, or enforce the immutability of the map, before passing the event data to an Event Handler.
To publish an event, the Event Source must retrieve the Typed Event Bus service from the OSGi service registry. The Event Source then creates an event object and calls one of the Typed Event Bus service's methods to publish the event. Event publication is asynchronous, meaning that when a call to the Typed Event Bus returns there is no guarantee that all, or even any, listeners have been notified.
Events are always published to a topic. The topic of an event defines the schema of the event. Topics exist in order to give Event Consumers information about the schema of the event, and the opportunity to register for just the events they are interested in. When a topic is designed, its name should not include any other information, such as the publisher of the event or the data associated with the event, those parts are intended to be stored in the event properties.
The topic therefore serves as a first-level filter for determining which handlers should receive the event. Typed Event service implementations use the structure of the topic to optimize the dispatching of the events to the handlers. The following example code demonstrates how to send an event to a topic.
public class ExampleEvent {
public String message;
}
@Component
public class ExampleEventSource {
@Reference
TypedEventBus bus;
public void sendEvent() {
ExampleEvent event = new ExampleEvent();
event.message = "The time is " + LocalDateTime.now();
bus.deliver("org/osgi/example/ExampleEvent", event);
}
}
Topics are arranged in a hierarchical namespace. Each level is
defined by a token and levels are separated by solidi ('/'
\u002F
). More precisely, the topic must conform to the following
grammar:
// For further information see General Syntax Definitions in Core
topictoken :: ( jletterordigit | '-' ) +
topic ::= topictoken ( '/' topictoken ) *
Topics should be designed to become more specific when going from left to right. Consumers can provide a prefix that matches a topic, using the preferred order allows a handler to minimize the number of prefixes it needs to register.
Topics are case-sensitive. As a convention, topics should follow
the reverse domain name scheme used by Java packages to guarantee
uniqueness. The separator must be a solidus ('/' \u002F
)
instead of the full stop ('.' \u002E
).
This specification uses the convention
fully/qualified/package/ClassName/ACTION
. If necessary, a
pseudo-class-name is used.
In many cases the name of a topic contains no information other than defining the schema of the events sent on that topic. Therefore, when publishing a Typed Event to the Typed Event Bus, the Typed Event implementation is able to automatically generate a topic name based on the the type of the event object being published.
For the deliver(Object) method on the Typed Event Bus where no topic
string is provided, the implementation must create a topic string using
the fully qualified class name of the event object. To convert the class
name into a valid topic the full stop .
separators must be
converted into solidus /
separators. A non-normative
example implementation follows:
public void deliver(Object event) {
String topicName = event.getClass().getName().replace('.', '/');
this.deliver(topicName, event);
}
The following example demonstrates how an Event Source can make use of an automatically generated topic name.
package org.osgi.example;
public class ExampleEvent {
public String message;
}
@Component
public class ExampleEventSource {
@Reference
TypedEventBus bus;
public void sendEvent() {
ExampleEvent event = new ExampleEvent();
event.message = "The time is " + LocalDateTime.now();
// This event will be delivered to the
// topic "org/osgi/example/ExampleEvent"
bus.deliver(event);
}
}
The TypedEventBus
implementation must be thread safe
and allow for simultaneous event publication from multiple threads. For
any given source thread, events must be delivered in the same order as
they were published by that thread. Events published by different
threads, however, may be delivered in a different order from the one in
which they were published.
For example, if thread A publishes events 1, 2 and 3, while thread B publishes events 4, 5 and 6, then the events may be delivered:
-
1, 2, 3, 4, 5, 6
-
4, 1, 2, 5, 6, 3
-
and so on
but events will never be delivered 1, 2, 6, 4, 5, 3
Event Consumers can receive events by registering an appropriate Event Handler service in the Service Registry. This is a TypedEventHandler to receive events as type-safe objects, or an UntypedEventHandler to receive events as untyped Map structures.
Published events are then delivered, using the whiteboard pattern, to any Event Handler service which has registered interest in the topic to which the event was published.
Typed Events are received by registering a
TypedEventHandler
implementation. This service has a single
method notify
which receives the String topic name and
Object event data. The TypedEventHandler implementation must be
registered as a service in the service registry using the
TypedEventHandler interface.
The TypedEventHandler interface is parameterized, and so it is expected that the implementation reifies the type parameter into a specific type. In this case the Typed Event implementation must adapt the Event object into the type defined by the TypedEventHandler implementation. Implementations of this specification are free to choose their own adaptation mechanism, however it must guarantee at least the same functionality as Converter Specification.
A simple example of receiving a typed event follows:
public class ExampleEvent {
public String message;
}
@Component
public class ExampleTypedConsumer implements TypedEventHandler<ExampleEvent> {
@Override
public void notify(String topic, ExampleEvent event) {
System.out.println("Received event: " + event.message);
}
}
If the TypedEventHandler implementation is unable to reify the
type, or the required type is more specific than the reified type, then
the Typed Event Handler must be registered with the
event.type
service property. This property has a string
value containing the fully-qualified type name of the type that the
Typed Event Handler expects to receive. This type must be loaded by the
Typed Event implementation using the classloader of the bundle which
registered the Typed Event Handler service. The loaded type must then be
used as the target type when converting events. For example:
public class ExampleEvent {
public String message;
}
public class SpecialisedExampleEvent extends ExampleEvent {
public int sequenceId = Integer.MIN_VALUE;
}
@Component
@EventType(SpecialisedExampleEvent.class)
public class ExampleTypedConsumer implements TypedEventHandler<ExampleEvent> {
@Override
public void notify(String topic, ExampleEvent event) {
System.out.println("Received event: " + event.message);
// The event will always be of type SpecialisedExampleEvent
System.out.println("Event sequence id was " +
((SpecialisedExampleEvent) event).sequenceId);
}
}
By default the reified type of the TypedEventHandler will be used
as the target topic for the Event Handler. If the
event.type
property is set then this is used as the default
topic instead of the reified type. To use a specific named topic the
Typed Event Handler service may be registered with an
event.topics
service property specifying the topic(s) as a
String+ value.
public class ExampleEvent {
public String message;
}
@Component
@EventTopics({"foo", "foo/bar"})
public class ExampleTypedConsumer implements TypedEventHandler<ExampleEvent> {
@Override
public void notify(String topic, ExampleEvent event) {
System.out.println("Event received on topic: " + topic +
" with message: " + event.message);
}
}
Untyped Events are received by registering an
UntypedEventHandler
implementation. This service has a
single method notifyUntyped which receives the String
topic
name and Map
event data. The Untyped Event Handler
implementation must be registered as a service in the service registry
using the UntypedEventHandler
interface.
When delivering an event to an Untyped Event Handler the Typed Event Service must, if necessary, convert the event data to a nested map structure.
The event.topics
service property must be used when
registering an Untyped Event Hander service. If it is not, then no
events will be delivered to that Untyped Event Handler service.
public class ExampleEvent {
public String message;
}
@Component
@EventTopics({"foo", "foo/bar"})
public class ExampleUntypedConsumer implements UntypedEventHandler {
@Override
public void notifyUntyped(String topic, Map<String,Object> event) {
System.out.println("Event received on topic: " + topic
+ " with message: " + event.get("message"));
}
}
The event.topics
property may contain one or more
wildcard topics. These are Strings which contain a topic name and append
“/*”. This value means that the Event Handler must be called for Events
sent to sub-topics of the named topic. For example the component:
@Component
@EventTopics("foo/*")
public class ExampleUntypedConsumer implements UntypedEventHandler {
@Override
public void notifyUntyped(String topic, Map<String,Object> event) {
System.out.println("Event received on topic: " + topic
+ " with message: " + event.get("message"));
}
}
would receive events sent to the topics foo/bar
and
foo/baz
, but not the topics foo
or
foobar/fizzbuzz
.
The *
character in a wildcard topic must always
follow a solidus /
character, and must be the final
character in the topic string, meaning that topic names such as
foo*
and foo/*/bar
are not valid. The only
exception to this rule is that it is valid to use the topic name
*
to receive events on all topics.
While it is valid to do so, using the topic *
is not
typically recommended. For a mechanism to monitor the events flowing
through the system see Monitoring Events.
Unhandled Events are events sent by an Event Source but which have no Event Handler service listening to their topic. Rather than these events being discarded, the Typed Event implementation will search the service registry for services implementing UnhandledEventHandler.
If any services are found then the Typed Event implementation will
call the notifyUnhandled
method passing the topic name and
event data to all of the registered Unhandled Event Handler
services.
public class ExampleEvent {
public String message;
}
@Component
public class ExampleUnhandledConsumer implements UnhandledEventHandler {
@Override
public void notifyUnhandled(String topic, Map<String,Object> event) {
System.out.println("Unhandled Event received on topic: " + topic);
}
}
Sometimes the use of a topic is insufficient to restrict the
events received by an event consumer. In these cases the consumer can
further restrict the events that they receive by using a filter. The
filter is supplied using the event.filter
service property,
the value of which is an LDAP filter string. This filter is applied to
the event data, and only events which match the filter are delivered to
the event handler service.
Complex events may contain nested data structures, such as DTOs,
as values in the event data. As LDAP filtering is only designed to
match against simple data this means that some event properties cannot
be filtered using the event.filter
property. The event
filter is therefore only suitable for use in matching top-level event
properties.
Note that the use of a filter is different from receiving an
event and choosing to ignore it based on its data. If an event fails
to match the filter supplied by an event handler service then it is
not delivered to that event handler. This means
that the event data remains eligible to be sent to an
UnhandledEventHandler
unless another event handler does
receive it. An event that is received, but ignored, by an event
handler service does count as having been
delivered, and so will never be sent to an
UnhandledEventHandler
.
Event Handler implementations are called by the Typed Event Bus implementation, and are expected:
-
Not to throw exceptions from their callback method
-
To return quickly - any long running tasks should be moved to another thread
If a Typed Event Bus implementation detects an Event Handler that is behaving incorrectly, either by throwing exceptions, or by taking a long time to process the event, or some other problem, then the implementation may block further event delivery to that Event Handler.
If an Event Handler is blocked by the event implementation then this situation must be logged. Also, if a blocked Event Handler service is updated then the block must be removed by the implementation. If the updated service continues to behave incorrectly then the block may be reinstated.
The service properties that can be used to configure an Event Handler service are outlined in the following table.
Table 157.1 Service properties applicable to Event Handler services
Service Property Name | Type | Description |
---|---|---|
event.topics |
String+ |
Declares the topic pattern(s) for which the service
should be called. This service property is
required for
See TYPED_EVENT_TOPICS. |
event.type |
String |
Defines the target type into which events should be
converted before being passed to the Event Handler service. This
service property is forbidden for
See TYPED_EVENT_TYPE. |
event.filter |
String |
Defines an LDAP filter which should be tested
against the properties in the event data. Only events which pass
the filter will be passed to the the Event Handler service. Ths
service property is permitted for both
See TYPED_EVENT_FILTER. |
There are several possible error scenarios for Event Handlers:
-
TypedEventHandler
- If the target event type is not discoverable, that is there is no reified type information, nor is there anevent.type
property, then the target type for the event is not known. In this situation there is no way for the Typed Event implementation to correctly target an event schema, and theTypedEventHandler
must be ignored. The implementation must write a message to the log indicating which service is being ignored. -
TypedEventHandler
- If the target event type is discoverable but cannot be loaded using the class loader of the bundle which registered the Typed Event Handler service then there is no way for the Typed Event implementation to correctly target an event schema, and the Event Handler must be ignored. The implementation must write a message to the log indicating which service is being ignored. -
All Handler Types - If the event data cannot be adapted to the target type, that is the incoming data cannot be transformed due to badly mismatched property names or values, then that specific Event cannot be submitted to the Handler. The Typed Event implementation must write a message to the log indicating which service failed to receive the event. If this error occurs repeatedly then the Typed Event implementation may choose to deny list and ignore the Event Handler service. Deny listing decisions must be written to the log.
-
All Handler Types - If the
event.topics
property contains one or more invalid values then the Event Handler service must be ignored. The implementation must write a message to the log indicating which service is being ignored.
The Typed Event implementation must register a Typed Event Bus service in the service registry. This service must implement and advertise the TypedEventBus interface.
It is not possible to know that an Event cannot be delivered until delivery is attempted. It is therefore not possible (or acceptable, given the asynchronous nature of delivery) to throw an exception to the sender of an event if there are problems delivering the event. The Event Bus service should not throw exceptions from any publication methods except:
-
NullPointerException
if the event data isnull
. -
IllegalArgumentException
if a topic name is supplied and it violates the topic name syntax.
An important part of a software system is the ability to monitor it appropriately to determine whether it is functioning correctly, without having the measurements disrupt the system. To this end the Typed Event implementation must register a TypedEventMonitor service which can be used to monitor the flow of events through the Event Bus.
Events flowing through the Typed Event Bus can be monitored using
one of the monitorEvents
methods from the
TypedEventMonitor
service. These methods return a PushStream
which delivers MonitorEvent instances each time an event is sent via the
TypedEventBus
. The monitor events contain the event topic,
the event data, and a timestamp indicating when the event was sent.
In a running system it is often useful for monitoring tools to
replay recent data immediately after a problem has occurred. For that
reason Typed Event Monitor instances may store past events so that they
can be replayed if requested. There are two monitorEvents
methods capable of replaying history:
-
monitorEvents(int) takes an
int
representing the number of past events that should be replayed from the cached history -
monitorEvents(Instant) takes an
Instant
, representing the time in the past from which the stream of monitoring events should start.
Note that storing Event History is considered a best-effort option and it is not required that the implementation supply the full set of requested events. If insufficient past events are available then the implementation must provide the maximum amount of history available.
The Typed Event implementation bundle must provide the osgi.implementation
capability with the name TYPED_EVENT_IMPLEMENTATION. This capability can be used by provisioning
tools and during resolution to ensure that a Typed Event implementation
is present. The capability must also declare a uses constraint for the
org.osgi.service.typedevent
package and provide the version
of this specification:
Provide-Capability: osgi.implementation;
osgi.implementation="osgi.typedevent";
uses:="org.osgi.service.typedevent";
version:Version="1.0"
The RequireTypedEvent annotation can be used to require this capability.
This capability must follow the rules defined for the osgi.implementation Namespace.
The bundle providing the Typed Event Bus service must provide
capabilities in the osgi.service
namespace representing the services it is required to register. This
capability must also declare uses constraints for the relevant service
packages:
Provide-Capability: osgi.service;
objectClass:List<String>="org.osgi.service.typedevent.TypedEventBus";
uses:="org.osgi.service.typedevent",
osgi.service;
objectClass:List<String>="org.osgi.service.typedevent.monitor.TypedEventMonitor";
uses:="org.osgi.service.typedevent.monitor"
This capability must follow the rules defined for the osgi.service Namespace.
The TopicPermission class allows fine-grained control over which bundles may post events to a given topic and which bundles may receive those events.
The target parameter for the permission is the topic name.
TopicPermission
classes uses a wildcard matching algorithm
similar to the BasicPermission
class, except that solidi
('/' \u002F
) are used as separators instead of full stop
characters. For example, a name of a/b/*
implies
a/b/c
but not x/y/z
or
a/b
.
There are two available actions: PUBLISH
and
SUBSCRIBE
. These control a bundle's ability to either
publish or receive events, respectively. Neither one implies the
other.
Bundles that need to consume events must be granted permission to
register the appropriate handler service. For Example:
ServicePermission
[org.osgi.service.typedevent.TypedEventHandler
,
REGISTER
] or
ServicePermission
[org.osgi.service.typedevent.UntypedEventHandler
,
REGISTER
] or
ServicePermission
[org.osgi.service.typedevent.UnhandledEventHandler
,
REGISTER
]. In addition, bundles that consume events require
TopicPermission[ <topic>, SUBSCRIBE ]
for each topic
they want to be notified about.
Bundles that need to publish events must be granted permission to
get the TypedEventBus
service, that is
ServicePermission[ org.osgi.service.typedevent.TypedEventBus,
GET]
so that they may retrieve the Typed Event Bus and use it. In
addition, event sources require TopicPermission[ <topic>,
PUBLISH]
for each topic they want to send events to. This
includes any default topic names that are used when publishing
Bundles that need to monitor events flowing through the bus must
be granted permission to get the TypedEventMonitor
service,
that is ServicePermission[
org.osgi.service.typedevent.monitor.TypedEventMonitor, GET]
so
that they may retrieve the Typed Event Monitor and use it.
Only a bundle that provides a Typed Event implementation should be
granted ServicePermission[
org.osgi.service.typedevent.TypedEventBus, REGISTER]
and
ServicePermission[
org.osgi.service.typedevent.monitor.TypedEventMonitor, REGISTER]
to register the services defined by this specification.
The Typed Event implementation must be granted
ServicePermission[org.osgi.service.typedevent.TypedEventHandler,
GET]
,
ServicePermission[org.osgi.service.typedevent.UntypedEventHandler,
GET]
,
ServicePermission[org.osgi.service.typedevent.UnhandledEventHandler,
GET]
,
ServicePermission[org.osgi.service.typedevent.TypedEventBus,
REGISTER]
and
ServicePermission[org.osgi.service.typedevent.monitor.TypedEventMonitor,
REGISTER]
as these actions are all required to implement the
specification.
During an event notification, the Typed Event implementation's
Protection Domain will be on the stack above the handler's Protection
Domain. Therefore, if a handler needs to perform a secure operation
using its own privileges, it must invoke the doPrivileged
method to isolate its security context from that of its caller.
The event delivery mechanism must not wrap event notifications in
a doPrivileged
call.
Typed Event Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.typedevent; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.typedevent; version="[1.0,1.1)"
-
TopicPermission
- A bundle's authority to publish or subscribe to typed events on a topic. -
TypedEventBus
- The Typed Event service. -
TypedEventConstants
- Defines standard names for Typed Event properties. -
TypedEventHandler
- Listener for Typed Events. -
UnhandledEventHandler
- Listener for Unhandled Events. -
UntypedEventHandler
- Listener for Untyped Events.
A bundle's authority to publish or subscribe to typed events on a topic.
A topic is a slash-separated string that defines a topic.
For example:
org / osgi / service / foo / FooEvent / ACTION
Topics may also be given a default name based on the event type that is published to the topic. These use the fully qualified class name of the event object as the name of the topic.
For example:
com.acme.foo.event.EventData
TopicPermission
has two actions: publish
and
subscribe
.
Thread-safe
Topic name.
publish
,subscribe
(canonical order).
Defines the authority to publish and/or subscribe to a topic within the Typed Event service specification.
The name is specified as a slash-separated string. Wildcards may be used. For example:
org/osgi/service/fooFooEvent/ACTION
com/isv/*
*
A bundle that needs to publish events on a topic must have the
appropriate TopicPermission
for that topic; similarly, a bundle
that needs to subscribe to events on a topic must have the appropriate
TopicPermssion
for that topic.
The object to test for equality with this
TopicPermission
object.
Determines the equality of two TopicPermission
objects.
This method checks that specified TopicPermission
has the same
topic name and actions as this TopicPermission
object.
true
if obj
is a TopicPermission
, and has
the same topic name and actions as this TopicPermission
object; false
otherwise.
Returns the canonical string representation of the
TopicPermission
actions.
Always returns present TopicPermission
actions in the following
order: publish
,subscribe
.
Canonical string representation of the TopicPermission
actions.
Returns the hash code value for this object.
A hash code value for this object.
The target permission to interrogate.
Determines if the specified permission is implied by this object.
This method checks that the topic name of the target is implied by the
topic name of this object. The list of TopicPermission
actions
must either match or allow for the list of the target object to imply the
target TopicPermission
action.
x/y/*,"publish" -> x/y/z,"publish" is true
*,"subscribe" -> x/y,"subscribe" is true
*,"publish" -> x/y,"subscribe" is false
x/y,"publish" -> x/y/z,"publish" is false
true
if the specified TopicPermission
action is
implied by this object; false
otherwise.
The Typed Event service. Bundles wishing to publish events must obtain this service and call one of the event delivery methods.
Thread-safe
Consumers of this API must not implement this type
The event to send to all listeners which subscribe to the topic of the event.
Initiate asynchronous, ordered delivery of an event. This method returns to the caller before delivery of the event is completed. Events are delivered in the order that they are received by this method.
The topic for this event will be automatically set to the fully qualified type name for the supplied event object.
Logically equivalent to calling
deliver(event.getClass().getName().replace('.', '/'), event)
NullPointerException
– if the event object is null
The topic to which this event should be sent.
The event to send to all listeners which subscribe to the topic.
Initiate asynchronous, ordered delivery of an event. This method returns to the caller before delivery of the event is completed. Events are delivered in the order that they are received by this method.
NullPointerException
– if the event object is null
IllegalArgumentException
– if the topic name is not valid
The topic to which this event should be sent.
A Map representation of the event data to send to all listeners which subscribe to the topic.
Initiate asynchronous, ordered delivery of event data. This method returns to the caller before delivery of the event is completed. Events are delivered in the order that they are received by this method.
NullPointerException
– if the event map is null
IllegalArgumentException
– if the topic name is not valid
Defines standard names for Typed Event properties.
Consumers of this API must not implement this type
The name of the service property used to indicate a filter that should be applied to events from the TYPED_EVENT_TOPICS. Only events which match the filter will be delivered to the Event Handler service.
If this service property is not present then all events from the topic(s) will be delivered to the Event Handler service.
The name of the implementation capability for the Typed Event specification
The version of the implementation capability for the Typed Event specification
The name of the service property used to indicate the topic(s) to which an a TypedEventHandler or UntypedEventHandler service is listening.
If this service property is not present then the reified type parameter from the TypedEventHandler implementation class will be used to determine the topic.
The name of the service property used to indicate the type of the event objects received by a TypedEventHandler service.
If this service property is not present then the reified type parameter from the TypedEventHandler implementation class will be used.
The type of the event to be received
Listener for Typed Events.
TypedEventHandler
objects are registered with the Framework service
registry and are notified with an event object when an event is sent.
TypedEventHandler
objects are expected to reify the type parameter
T
with the type of object they wish to receive when implementing this
interface. This type can be overridden using the
TypedEventConstants.TYPED_EVENT_TOPICS service property.
TypedEventHandler
objects may be registered with a service property
TypedEventConstants.TYPED_EVENT_TOPICS whose value is the list of
topics in which the event handler is interested.
For example:
String[] topics = new String[] {
"com/isv/*"
};
Hashtable ht = new Hashtable();
ht.put(EventConstants.TYPE_SAFE_EVENT_TOPICS, topics);
context.registerService(TypedEventHandler.class, this, ht);
Thread-safe
The topic to which the event was sent
The event that occurred.
Called by the TypedEventBus service to notify the listener of an event.
Listener for Unhandled Events.
UnhandledEventHandler
objects are registered with the Framework
service registry and are notified with an event object when an event is sent,
but no other handler is found to receive the event
Thread-safe
The topic to which the event was sent
The event that occurred.
Called by the TypedEventBus service to notify the listener of an unhandled event.
Listener for Untyped Events.
UntypedEventHandler
objects are registered with the Framework service
registry and are notified with an event object when an event is sent.
UntypedEventHandler
objects must be registered with a service
property TypedEventConstants.TYPED_EVENT_TOPICS whose value is the
list of topics in which the event handler is interested.
For example:
String[] topics = new String[] {
"com/isv/*"
};
Hashtable ht = new Hashtable();
ht.put(EventConstants.TYPE_SAFE_EVENT_TOPICS, topics);
context.registerService(UntypedEventHandler.class, this, ht);
Thread-safe
The topic to which the event was sent
The event that occurred.
Called by the TypedEventBus service to notify the listener of an event.
Typed Event Annotations Package Version 1.0.
This package contains annotations that can be used to require the Typed Event implementation.
Bundles should not normally need to import this package as the annotations are only used at build-time.
-
RequireTypedEvent
- This annotation can be used to require the Typed Event implementation.
This annotation can be used to require the Typed Event implementation. It can be used directly, or as a meta-annotation.
This annotation is applied to several of the Typed Event component property type annotations meaning that it does not normally need to be applied to Declarative Services components which use the Typed Event specification.
1.0
CLASS
TYPE
, PACKAGE
Typed Event Monitoring Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.typedevent.monitor; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.typedevent.monitor; version="[1.0,1.1)"
-
MonitorEvent
- A monitoring event. -
TypedEventMonitor
- The EventMonitor service can be used to monitor the events that are sent using the EventBus, and that are received from remote EventBus instances
A monitoring event.
Consumers of this API must not implement this type
The EventMonitor service can be used to monitor the events that are sent using the EventBus, and that are received from remote EventBus instances
Thread-safe
Consumers of this API must not implement this type
Get a stream of events, starting now.
A stream of event data
The requested number of historical events, note that fewer than this number of events may be returned if history is unavailable, or if insufficient events have been sent.
Get a stream of events, including up to the requested number of historical data events.
A stream of event data
The requested time after which historical events, should be included. Note that events may have been discarded, or history unavailable.
Get a stream of events, including historical data events prior to the supplied time
A stream of event data
Typed Event Component Property Types Package Version 1.0.
When used as annotations, component property types are processed by tools to generate Component Descriptions which are used at runtime.
Bundles wishing to use this package at runtime must list the package in the Import-Package header of the bundle's manifest.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.typedevent.propertytypes; version="[1.0,2.0)"
-
EventFilter
- Component Property Type for the TypedEventConstants.TYPED_EVENT_FILTER service property of an Event Handler service. -
EventTopics
- Component Property Type for the TypedEventConstants.TYPED_EVENT_TOPICS service property of a TypedEventHandler or UntypedEventHandler service. -
EventType
- Component Property Type for the TypedEventConstants.TYPED_EVENT_TYPE service property of an TypedEventHandler service.
Component Property Type for the TypedEventConstants.TYPED_EVENT_FILTER service property of an Event Handler service.
This annotation can be used on an TypedEventHandler or UntypedEventHandler component to declare the value of the TypedEventConstants.TYPED_EVENT_FILTER service property.
Component Property Types
CLASS
TYPE
Service property specifying the event filter for a TypedEventHandler or UntypedEventHandler service.
The event filter.
Component Property Type for the TypedEventConstants.TYPED_EVENT_TOPICS service property of a TypedEventHandler or UntypedEventHandler service.
This annotation can be used on a component to declare the values of the TypedEventConstants.TYPED_EVENT_TOPICS service property.
Component Property Types
CLASS
TYPE
Service property specifying the Event
topics of interest to an
TypedEventHandler or UntypedEventHandler service.
The event topics.
Component Property Type for the TypedEventConstants.TYPED_EVENT_TYPE service property of an TypedEventHandler service.
This annotation can be used on an TypedEventHandler component to declare the value of the TypedEventConstants.TYPED_EVENT_TYPE service property.
Component Property Types
CLASS
TYPE
Service property specifying the EventType
for a
TypedEventHandler service.
The event filter.