Newton: Component Model
Motivation
Newton provides a distributed component model.
To be useful, a distributed component model needs to address the fundamental differences between local and distributed computing, as famously expressed in The Eight Fallacies of Distributed Computing and A note on distributed computing.
Another consideration is ease of development. The recent plethora of POJO based application frameworks such as Spring, and their rapid adoption by the development community serve to highlight the advantages of lightweight development models. That is, separation of domain model from infrastructure concerns, increased productivity and maintainability, and reduced vendor lock-in.
It is with these considerations in mind that Newton has been developed. The objective is to provide a lightweight development model for distributed components in which the unavoidable realities of distributed computing are directly addressed.
Key technologies
The world in which a distributed component lives is a highly dynamic one, subject to unforeseen failures and network state ambiguities. Also administration of distributed systems, for example deployment and clean-up of resources, is currently an onerous task, and stands in the way of all efforts to develop autonomous distributed systems. Two key technologies Newton uses to address these concerns are OSGi, which is central to the whole Newton component model, and Jini, which is the basis of Newton's remoting infrastructure. Newton also makes use of SCA to describe describe assemblies of componenents, or composites in SCA terminology.
OSGi
OSGi provides a highly dynamic and well designed services model for a single JVM. OSGi's unit of deployment, the Bundle, uses a state of the art peer classloading model, rather than a traditional hierarchical classloading model. This enables OSGi to guarantee a consistent class view across the container and avoids the classloader related class mismatch errors that plague hierarchical approaches. Bundles also have a well defined lifecycle from install to uninstall. OSGI bundles also improve on the encapsulation provided by traditional jar files, publically exposing only those classes which form part of their intended API, and keeping the rest private. Physically bundles are just jar files with extra metadata, via which inter bundle dependencies can be resolved.
OSGi also makes use of an internal services registry, via which services created during the lifetime of different bundles can find each other.
Additionally, OSGi has a well thought through security model at both Bundle and Service level.
OSGi's rich and highly dynamic model made it a natural choice for Newton, in which the container itself is built out of OSGi bundles, and in which end user component code is deployed in bundles.
At present Newton runs in an OSGi R4 container. Knopflerfish and Equinox are supported directly. We expect to add Felix to this list before too long.
Jini
Jini provides a service oriented model that explicitly addresses the realities of distributed computing. In particular Jini provides a distributed registry, via which remote services can find each other, and makes extensive use of leasing to ensure reclamation of resources that are not explicitly release by failed clients. Jini also provides a high quality extensible RMI stack, and strong support for network level and remote code security.
Newton uses Jini's remote registry to track and wire up the remote dependencies of Newton components. Future releases of Newton will make use of Jini's distributed transaction management capabilities and of Javaspaces for distributed process coordination.
SCA
SCA is a language, runtime and protocol agnostic component wireup standard. Essentially it allows for the specification of a hierarchical assembly of components, either within a single runtime, or distributed across disparate systems.
Newton's implementation of SCA is highly dynamic. Starting with an SCA descriptor, Newton is able to instantiate a distributed system across available hardware, provisioning all necessary resources and wiring up the SCA composites without any need for administrator assistance. During its lifetime Newton monitors the system and responds to problems. Newton also monitors the SCA descriptor, propagating changes to this document onto the deployed system. When the SCA system is no longer required Newton is able to completely deprovision it and to release all of the resources it used.
Component model
Overview
The minimal unit of deployment in Newton is an SCA composite running within a single process with code backed by a single OSGi bundle known as a factory bundle. Factory bundles either contain or import all the class and resource files necessary to instantiate composites of a given type, and can be used to create many composite instances of this type. The way in which a factory bundle creates and manages its composites is specified by the composite template(s) it contains. Composite templates are SCA descriptors specifying the overall structure of the composites a given factory bundle can create, including their lifecycle management, provided services and required references.
To install a Newton composite its instance descriptor is given to the Newton installer. This descriptor is also SCA based, and modifies a composite template, overriding it with instance specific information. The composite is removed when its descriptor is removed.
Newton composites can provide and refer to multiple services. Throughout a composite's lifetime Newton monitors these and wires them together based on their binding type and the metadata with which they are annotated. Newton's bindings notice when a service dependency is lost due to failure, uninstallation or disconnection, and respond by trying to rewire the dependency, perhaps to an alternative service.
When the first Newton composite of a given type is installed Newton installs the corresponding factory bundle and all of its dependencies. When the last composite that type is uninstalled Newton's bundle garbage collection mechanism removes any bundles that are no longer in use.
Higher level SCA composites and systems can be built out of the minimal composites backed by factory bundles. Newton manages these larger composites as follows:
Given an SCA based description of some target state, Newton deploys, instantiates and wires up all necessary composites to reach this state. Newton then monitors the deployed system for deviations from this target state and works to get back to it. For example, if Newton notices a composite has failed it will respond by reprovisioning a new one. Newton's notion of target state is richer than simple composite counting, and can be based on any available system metrics, so that for example, part of the target state could be an invocation rate SLA.
Bundles and and other files are made available to Newton when they are added to the Content Distribution System (CDS). Each item of CDS content belongs to a zone. Content in the boot zone is private to each container instance and includes, for example, those bundles required during the bootstrap phase, before the remote part of Newton is active. On the other hand all Newton containers belonging to a given Fabric (i.e. multi-container Newton system) have the same view of Content in CDS's remote zone. Since the remote zone is visible across multiple containers, any bundle stored in it can be installed on demand by any container in the Fabric.
Composite Structure
Newton's minimal deployable units are non nested SCA composites containing components which wrap the composite's service implementations. Components have an implementation type which describes how to wrap a particular kind of underlying implementation. At the moment Newton provides implementations based on POJOs and on Jini Starter Service services. However, the mechanism is highly extensible, as illustrated by the Spring implementation type which was initially developed as an optional add-in for Newton, but is now bundled as standard.
Composites provide services to other composites and have references which express their own external service requirements. The technology used to connect services and references is expressed by their binding. At the moment Newton supports local OSGi and remote Jini based bindings, although users are shielded from most of their complexity. Components within the same composite can also refer to each others' services directly. The following diagram illustrates this model.

On this diagram the internal links represent wires between services and references within a single component.
Within Newton, service and reference bindings are annotated with binding specific metadata. The OSGi and Jini based bindings that Newton currently supports have a shared approach to metadata. Each annotates its services with multiple name-value pair attributes, in which the values are wrappers around simple Java types. On the other hand, references are annotated with LDAP style filters over service attributes. Newton connects references to services with attributes satisfying their LDAP filter.
The number of matching services a reference wants to be connected to is controlled by the import's multiplicity. Multiplicity examples are 1..1 for a mandatory service, 0..1 for an optional one, and 0..* when all matches are sought.
The structure of a given composite type, and the way in which it creates its components is specified by its SCA based composite template descriptor. Individual composites are described by SCA based composite instance descriptors referencing and overriding this template. A descriptor example is shown below - this one is taken from the Chainlink Demo.
<?xml version="1.0"?>
<composite name="braceLinkTemplate">
<description>chainlink demo brace link</description>
<reference name="nextLink" multiplicity="0..1">
<interface.java
interface="org.cauldron.newton.test.bundles.chainlink.interfaces.Link"/>
<binding.osgi/>
</reference>
<service name="brace-link-export">
<interface.java
interface="org.cauldron.newton.test.bundles.chainlink.interfaces.Link"/>
<binding.osgi/>
</service>
<component name="brace-link">
<description>A brace decorated chain link</description>
<property name="linkName" value="Unnamed" type="string"/>
<reference name="nextLink"/>
<implementation.java.callback
impl="org.cauldron.newton.test.bundles.chainlink.brace.BraceLink"/>
</component>
<wire>
<source.uri>nextLink</source.uri>
<target.uri>brace-link/nextLink</target.uri>
</wire>
<wire>
<source.uri>brace-link</source.uri>
<target.uri>brace-link-export</target.uri>
</wire>
</composite>
This composite has a reference to an interface called nextLink of type org.cauldron.newton.test.bundles.chainlink.interfaces.Link using the OSGi binding. If a suitable service can be found then the reference will be wired to it, but the multiplicity constraint of 0..1 means that it can function without one. If there was an LDAP filter on the reference it would be on the OSGi binding; we'll see one in a moment in the instance descriptor.
This composite creates one component called "brace-link". This component is wired to the brace-link-export service. It also requires a service called bracelink/nextLink, which is wired to the nextLink reference. The <property ..> tag specifies a configuration value which can be used by the service implementation.
This component creates and manages its dependencies using a POJO style "callback" lifecycle. The callback lifecycle creates components by instantiating the impl class using either an empty constructor or one taking a map holding the config values specified in the component's <config ..> tags. The callback lifecycle manages service dependencies by calling add<requirement-name> and remove<requirement-name> methods on the impl class. The impl class corresponding to this template is shown below.
package org.cauldron.newton.test.bundles.chainlink.brace;
import java.util.Map;
import org.apache.log4j.Logger;
import org.cauldron.newton.test.bundles.chainlink.interfaces.Link;
/**
* Callback style POJO component impl
*/
public class BraceLink implements Link {
private static final Logger log = Logger.getLogger(BraceLink.class);
private String linkName;
private Link next;
//the service config is passed to the constructor and used to
//determine the link name
public BraceLink(Map config) {
linkName = (String) config.get("linkName");
}
//invoked by the callback lifecycle whenever a link is connected
public void addNextLink(Link link) {
next = link;
}
//invoked by the callback lifecycle whenever a link is lost
public void removeNextLink(Link link) {
next = null;
}
public String append(String message) {
if (log.isDebugEnabled())
log.debug("appending [" + message + "] in " + linkName);
if (next != null && message.length() < 4096) {
return next.append(message + "->{" + linkName + "}");
}
else {
return message + "->{" + linkName + "}" + " [end of chain]";
}
}
//invoked by the callback lifecycle if available
public void destroy() {
log.debug("DESTROYED BraceLink: " + linkName);
}
}
To actually create an instance of a composite an SCA based instance descriptor is passed to the Newton installer. An instance descriptor corresponding to the above template is shown below.
<?xml version="1.0"?>
<composite name="LinkA">
<bundle.root bundle="chainlink-local-brace-bundle" version="1.0"/>
<include name="braceLinkTemplate"/>
<reference name="nextLink">
<binding.osgi filter="(tag=b)"/>
</reference>
<component name="brace-link">
<description>link A</description>
<property name="linkName" value="A-link" type="string"/>
</component>
<service name="brace-link-export">
<binding.osgi>
<attribute name="tag" value="a" type="string"/>
</binding.osgi>
</service>
</composite>
Here the <bundle.root ..> element specifies the factory bundle containing (or importing) the code needed to create the composite. The next line includes the template that this descriptor will override with instance information. The rest of the descriptor specifies instance specific binding information and configuration properties. Note how the reference binding now has an associated LDAP filter of (tag=b), the service binding is now annotated with tag=a, and the linkName property value has been redefined to give the instance a name.
Composite Lifecycle
When Newton composites are being installed, all that needs to be specified is their composite instance descriptor. Neither end users, nor higher level Newton facilities, such as those managing full SCA systems, need to be concerned about installing or uninstalling the bundles containing the composites's class and resource files. During composite installation the installer identifies the composite's factory bundle from its descriptor and delegates to it for the rest of the install process. It is important to understand that when the request to install a composite is received, the corresponding factory bundle may not be present. Newton solves this problem as follows.
Newton tracks bundle dependencies by maintaining an OBR index of all bundles in CDS. When the first instance decriptor of given type is passed to the installer, it uses this index to check that the factory bundle and all of its dependencies are installed, and then installs any that are missing. Next the factory bundle is started, after which it serves as a factory for turning instance descriptors corresponding to its template(s) into runtime composites.
For completeness we note that Newton uses a bundle garbage collection (BGC) mechanism to remove unused bundles. In the current case factory bundles are marked as BGC roots, which prevents both their removal and the removal of their dependencies by the BGC. After the last instance descriptor of a given type is removed from the installer, that composite type's factory bundle is stopped and its BGC root status is removed. This makes it and its dependencies eligible for removal by the BGC if they are not dependencies of another BGC root.
The install process just described is illustrated below.

Extensible composite instantiation pipeline.
The processes described above are all part of Newton's composite instantiation pipeline. This pipeline is extensible at several points, so that it can be adapted to support different component implementation types and transport bindings. These extensions can be implemented using Newton composites or non-Newton OSGi services.
The following diagram provides a simplified view of this pipeline and its extensibility points.

The steps shown correspond to the following
- The parser converts an XML based instance descriptor into a Java runtime representation of the same information. Parsing is extensible so that it can read any configuration information that used by the plugins to the other extensibility points.
- The runtime manager connects the SCA instance descriptor to the code needed to create the composite (using the process described earlier in this document) and uses it constrain the corresponding SCA template.
- The resulting SCA descriptor is turned into into a runtime instance of the composite. This involves creating all of the components in the composite using implementation type specific approaches. At the moment there are three implementation types. One for POJO style components with callback based lifecycles, another for POJO style components that are passed their dependencies at construction time, and a third that wraps Jini Starter Service based services. A Spring implementation type which demonstates the pluggable nature of implementation types is also available.
- The service bindings publish the component's services. These bindings are also easily exstensible. At the moment there are bindings for the OSGi and Jini. Future Newton releases are likely to support additional bindings, some based on alternate protocols, others on quality of service concerns.
- The references bindings track and wire up the component's references, rewiring them in response to change. These bindings are also easily exstensible. At the moment there are bindings for OSGi and Jini. Future Newton releases are likely to support additional bindings, some based on alternate protocols, others on quality of service concerns.


