This chapter outlines how to develop for and with enRoute, which is foremost Service Oriented Systems. This chapter is intended to be pragmatic and will not try to explain why certain mechanisms work. If you’re more interested in that then the principles chapter is more suitable.
Service Oriented Systems are built from the lowest level from a very simple concept: a service. A service is an instance registered with a broker whose role is defined by a service contract; a contract is specified in a Java package. A contract defines a number of roles and their behavior in the collaboration scenarios supported by that service. For example, in the Event Admin specification there are three roles, the event Handler, the Event Admin provider, and the event source. The contract specifies what happens when an event is posted and what the responsibilities of the specified roles are. The roles are specified in Java interfaces so that their syntactic rules can be enforced by the compiler.
The broker is dynamic, services can be registered at any time and also withdrawn. Services can be found by their role as well as service properties related to their roles. Services are a type of a publish-find-bind model. In OSGi terminology you register
a service (publish), you get
a service (bind), and you listen
to a service. Services are represented with the following symbol:
The purpose of a service is to abstract a well defined responsibility and its state.
A service component is an object that implements 0 or more roles. A service component can (dynamically) depend on a number of other services and uses any number of implementation classes. However, a service component should only collaborate with other components through services. Service components are active, that is, they can decide themselves when to start running without requiring a central registration. Service components can use libraries but should never use those libraries to exchange or share state. They should also not use static variables.
Components (diagram: parallelograms) can interact with external resources.
Service components are packaged in bundles, potentially many components in one bundle. A bundle is a JAR file with Java code and general resources described by a manifest. A bundle is a module where all its code is by default private. The manifest can declare some of its packages exported. Since the module will depend on other packages, the manifest explicitly declares the packages that are needed by its contents. Exported and imported packages should be restricted to service contracts and libraries.
A bundle is a reified entity in runtime with its own life cycle. When installed it will not be able to run until it is resolved. The OSGi Framework has the responsibility to wire bundles together so that the imports match corresponding exports. Before a bundle is active, none of its components may be active.
A library is a bundle without internal state and should therefore have no components or Bundle Activator. A library provides an API to do certain tasks but all observable state is maintained in instance variables and never in statics. Libraries should be started like all bundles but will not act differently whether they are started or not because they lack state. Libraries never register or use services.
The purpose of a library is to provide convenience functions for a specific area. Libraries do not provide substitution.
A framework hosts a number of bundles. Some services registered by those bundles can be exported, they can become available outside the framework as an endpoint.