RUNES Component Model

Our component model comprises the following elements: components, component types, interfaces, receptacles, connectors, connector factories, attributes and capsules. The API associated with the model is defined next in terms of the OMG's Interface Definition Language (IDL). In addition, the relationships between the various elements is shown diagrammatically (using UML) in the figure.
RUNES Component Model

Kernel API

In the model, components are the basic runtime units of encapsulation and deployment. They are instantiated at run-time from component types, such that each component type can be used to create multiple component instances at run-time. This is performed using the instantiate() operation in the kernel API, illustrated next. Components can be deleted as well, using destroy(). Component types can themselves be dynamically loaded and unloaded at runtime (see load() and unload()), which provides the basis for the dynamic nature of our programming model. As well as simply being able to load/unload functionality as required, we also use this dynamic capability to support the dynamic reconfiguration of components and their interconnections depending on context; e.g., changing a routing component on the basis of MAC-layer feedback. This feature proves very useful in the highly dynamic environments that we target.

interface Capsule : {
   ComponentType load(in Pattern p);
   void unload(in ComponentType t);
   Component instantiate(in ComponentType t);
   void destroy(in Component c);
   Connector connect(in Interface i, in Receptacle r, in ConnectorFactory cf);
   void setAttribute(in Entity e, in Attribute a);
   sequence getAttributes(in Entity e, in Pattern p);
   sequence getEntities(in Pattern p);
;}


Components offer their functionality through one or more interfaces each of which is defined in a programming language independent manner as a set of types and operation signatures. In addition, components that have dependencies on other components can express these dependencies in terms of one or more receptacles. This capability is of considerable help when components are dynamically deployed, as the required deployment environment of the new component is made clear and explicit. Such a component must have each of its receptacles connected (using connect()) to a corresponding interface on some external component before it can execute. This connection between a receptacle and an interface is explicitly represented in the model through a so-called connector, which is itself a component and therefore can be deleted using destroy().

The model also incorporates the notion of connector factories. These are components that create connectors that embody a specific piece of behaviour to be invoked every time a call is made over a given receptacle/interface connection. In this way, connectors may encapsulate arbitrary functionality and can thus be used to perform such functions as monitoring or intercepting communications between their associated receptacle and interface. Connector factories are passed as arguments to connect(); or, if a null argument is passed, a "default" connector factory is used which binds the receptacle directly to the interface. Note that connector factories are not normally used to abstract over network communications; rather, they are intended for "local" use only. Network communication is assumed to be encapsulated within middleware components and is thus transparent to the component model itself.

All of the foregoing entities (i.e., components, component types, interfaces, receptacles, and connectors) may be annotated with attributes. These are key/value pairs that can be used to express arbitrary meta-data. Attributes are managed using setAttribute() and getAttributes(). Finally, all of the foregoing entities reside inside a capsule which serves as a runtime component container, providing name space functionality. A capsule is typically implemented as an operating system address space although this is not mandatory. All the entities currently inside a capsule can be enumerated using the getEntities() operation.