Services

A service is an object that is registered to the framework service registry, associated with a set of specifications it implements and to properties.

The bundle that registers the service must keep the ServiceRegistration object returned by the framework. It allows to update the service properties and to unregister the service. This object shall not be accessible by other bundles/services. Finally, all services must be unregistered when their bundle is stopped.

A consumer can look for a service in the framework that matches a specification and a set of properties. The framework will return a ServiceReference object, which provides a read-only access to the description of its associated service: properties, registering bundle, bundles using it...

Properties

When registered and while it is available, the properties of a service can be set and updated by its provider.

Although, some properties are reserved for the framework; each service has at least the following properties:

Name Type Description
objectClass list of str List of the specifications implemented by this service
service.id int Identifier of the service. Unique in a framework instance

The framework also uses the following property to sort the result of a service look up:

Name Type Description
service.ranking int The rank/priority of the service. The lower the rank, the more priority

Service Factory

Warning

Service factories are a very recent feature of iPOPO and might be prone to bugs: please report any bug encounter on the project GitHub.

Note

Even if the Prototype Service Factories flag is available in the API, this kind of service factory is not yet handled by iPOPO.

A service factory is a pseudo-service with a specific flag, which can create individual instances of service objects for different bundles. Sometimes a service needs to be differently configured depending on which bundle uses the service. For example, the log service needs to be able to print the logging bundle’s id, otherwise the log would be hard to read.

A service factory is registered in exactly the same way as a normal service, using register_service(), with the factory set to True``. The only difference is an indirection step before the actual service object is handed out.

The client using the service need not, and should not, care if a service is generated by a factory or by a plain object.

A simple service factory example

class LongFactory:
    def get_service(self, bundle, registration):
        """
        Called each time a new bundle requires the service
        """
        return bundle.get_bundle_id()

    def unget_service(self, bundle, registration):
        """
        Called when a bundle has released all its references
        to the service
        """
        # Release connections, ...
        pass

bundle_context.register_service("long", LongFactory(), {}, factory=True)

Note

The framework will cache generated service objects. Thus, at most one service can be generated per client bundle.

API

The service provider has access to the ServiceRegistration object created by the framework when register_service() is called.

class pelix.framework.ServiceRegistration(framework, reference, properties, update_callback)

Represents a service registration object

Parameters:
  • framework – The host framework
  • reference – A service reference
  • properties – A reference to the ServiceReference properties dictionary object
  • update_callback – Method to call when the sort key is modified
get_reference()

Returns the reference associated to this registration

Returns:A ServiceReference object
set_properties(properties)

Updates the service properties

Parameters:properties – The new properties
Raises:TypeError – The argument is not a dictionary
unregister()

Unregisters the service

Consumers can access the service using its ServiceReference object, unique and constant for each service. This object can be retrieved using the BundleContext and its get_service_reference* methods. A consumer can check the properties of a service through this object, before consuming it.

class pelix.framework.ServiceReference(bundle, properties)

Represents a reference to a service

Parameters:
  • bundle – The bundle registering the service
  • properties – The service properties
Raises:

BundleException – The properties doesn’t contain mandatory entries

get_bundle()

Returns the bundle that registered this service

Returns:the bundle that registered this service
get_properties()

Returns a copy of the service properties

Returns:A copy of the service properties
get_property(name)

Retrieves the property value for the given name

Returns:The property value, None if not found
get_property_keys()

Returns an array of the keys in the properties of the service

Returns:An array of property keys.
get_using_bundles()

Returns the list of bundles that use this service

Returns:A list of Bundle objects

Finally, here are the methods of the BundleContext class that can be used to handle services:

class pelix.framework.BundleContext(framework, bundle)

The bundle context is the link between a bundle and the framework. It is unique for a bundle and is created by the framework once the bundle is installed.

Parameters:
  • framework – Hosting framework
  • bundle – The associated bundle
add_service_listener(listener, ldap_filter=None, specification=None)

Registers a service listener

The service listener must have a method with the following prototype:

def service_changed(self, event):
    '''
    Called by Pelix when some service properties changes

    event: A ServiceEvent object
    '''
    # ...
Parameters:
  • listener – The listener to register
  • ldap_filter – Filter that must match the service properties (optional, None to accept all services)
  • specification – The specification that must provide the service (optional, None to accept all services)
Returns:

True if the listener has been successfully registered

get_all_service_references(clazz, ldap_filter=None)

Returns an array of ServiceReference objects. The returned array of ServiceReference objects contains services that were registered under the specified class and match the specified filter expression.

Parameters:
  • clazz – Class implemented by the service
  • ldap_filter – Service filter
Returns:

The sorted list of all matching service references, or None

get_service(reference)

Returns the service described with the given reference

Parameters:reference – A ServiceReference object
Returns:The service object itself
get_service_reference(clazz, ldap_filter=None)

Returns a ServiceReference object for a service that implements and was registered under the specified class

Parameters:
  • clazz – The class name with which the service was registered.
  • ldap_filter – A filter on service properties
Returns:

A service reference, None if not found

get_service_references(clazz, ldap_filter=None)

Returns the service references for services that were registered under the specified class by this bundle and matching the given filter

Parameters:
  • clazz – The class name with which the service was registered.
  • ldap_filter – A filter on service properties
Returns:

The list of references to the services registered by the calling bundle and matching the filters.

register_service(clazz, service, properties, send_event=True, factory=False, prototype=False)

Registers a service

Parameters:
  • clazz – Class or Classes (list) implemented by this service
  • service – The service instance
  • properties – The services properties (dictionary)
  • send_event – If not, doesn’t trigger a service registered event
  • factory – If True, the given service is a service factory
  • prototype – If True, the given service is a prototype service factory (the factory argument is considered True)
Returns:

A ServiceRegistration object

Raises:

BundleException – An error occurred while registering the service

remove_service_listener(listener)

Unregisters a service listener

Parameters:listener – The service listener
Returns:True if the listener has been unregistered
unget_service(reference)

Disables a reference to the service

Returns:True if the bundle was using this reference, else False