tu sca ny 1 extending the tuscany java sca runtime 21 august 2006
TRANSCRIPT
1 tu sca ny
Extending The Tuscany Java SCA Runtime
21 August 2006
2 tu sca ny
Agenda
• Overview
• Extension Types
• Creating a Binding Extension
• Advanced Tuscany Programming Model
• Creating a Component Type Extension
3 tu sca ny
Overview
• The Tuscany core was designed to be as simple and small as possible• Focus on wiring/assembly
• Most capabilities provided as extensions• Component implementation types, e.g. Spring
• Support for Bindings
• Support for Policy/Qualities of Sevice
• Loading of XML
• The basic extension model is SCA• Extensions are “system services” which are SCA components
4 tu sca ny
Runtime Assembly
• The runtime is itself an SCA assembly
CreateRuntime
Component
CreateBootstrapDeployer
DeploySystem
Assembly
Locate Application Assemblies
Locate System Assembly
Deploy Application Assembly
Start Server
5 tu sca ny
Component Tree
• Composites form a containment hierarchy
• The hierarchy may be arbitrarily deep
• The runtime itself, DefaultRuntime, is a composite
• There are two runtime hierarchies• The application hierarchy
• End-user components
• The system hierarchy• Runtime extensions
6 tu sca ny
The SPI Package
• A separate SPI project has been created for extending the runtime• Extension code must never reference classes in core
• Besides being bad design, this type of code will break when deployed to hosts that enforce classloader isolation
• There is a test package for testcases to instantiate a few core implementation classes without directly referencing them (we should look to eliminate it if possible)
• tuscany-core is an implementation of spi
core
spiExtension
7 tu sca ny
Agenda
• Overview
• Extension Types
• Creating a Binding Extension
• Advanced Tuscany Programming Model
• Creating a Component Type Extension
8 tu sca ny
Base Extension Types
• Components
• Protocol Bindings
• Transport Bindings
• Data Bindings
• Policy
• Loaders
• Other types:• Scope contexts
• Wires
• Proxy generation
• Anything people can think of and attach to the runtime…
9 tu sca ny
Extension Package
• spi contains an extension package with abstract classes for base extensions• AtomicComponentExtension.java
• CompositeComponentExtension.java
• LoaderExtension.java
• ReferenceExtension.java
• ServiceExtension.java
• If extenders do not want to inherit from a base class, they can implement interfaces
10 tu sca ny
Extension Programming Model
• Extensions consist of a set of components that offer services• Are POJOs that follow the SCA Java programming model
• Extensions are contributed as composite components to the runtime
• There are a few programming model extensions for logging and advanced wiring that we will discuss later
11 tu sca ny
Agenda
• Overview
• Extension Types
• Creating a Binding Extension
• Advanced Tuscany Programming Model
• Creating a Component Type Extension
12 tu sca ny
Binding Invocation Through a Reference
• When a message reaches the end of the outbound reference wire, the TargetInvoker dispatches over a transport
OutboundInboundOutbound
Invoke on transport
AtomicComponent Composite Reference
13 tu sca ny
Binding Invocation Through a Service
• Invocation is deserialized from a transport and passed through the service invocationchain
OutboundInbound
Composite ServiceAtomicComponent
Inbound Invoke
Invoke from transport
14 tu sca ny
Creating a Binding Extension
• Bindings are used by Services and References
• Binding extensions produce either Services or References• Must create a Loader and Builder
• For references the builder produces an implementation of org.apache.tuscany.spi.componen.Reference
• For services the builder produces an implemenation of org.apache.tuscany.spi.component.Service
• Services may register servlets for incoming requests through org.apache.tuscany.spi.host.ServletHost
• References responsible for creating instances TargetInvoker, Services do not need to
load build connect
15 tu sca ny
A Loader
• Is an SCA Component
• Extends org.apache.tuscany.spi.extension.LoaderExtension
public class EchoBindingLoader extends LoaderExtension<EchoBinding> {
public static final QName BINDING_ECHO = new QName(XML_NAMESPACE_1_0, "binding.echo");
@Constructor public EchoBindingLoader(@Autowire LoaderRegistry registry) { super(registry); }
public QName getXMLType() { return BINDING_ECHO; }
public EchoBinding load(CompositeComponent parent, XMLStreamReader reader, DeploymentContext context)
throws XMLStreamException, LoaderException { return new EchoBinding(); }}
Returns the Binding model objectNormally, XML would be parsed with the reader
16 tu sca ny
A Builder
• Is an SCA Component
• Extends org.apache.tuscany.spi.extension.BindingBuilderExtension
public class EchoBuilder extends BindingBuilderExtension<EchoBinding> {
public SCAObject build(CompositeComponent parent, BoundReferenceDefinition<EchoBinding> definition, DeploymentContext context) { Class<?> interfaze = definition.getServiceContract().getInterfaceClass(); String name = definition.getName(); return new EchoReference(name, interfaze, parent, wireService); }
public SCAObject build(CompositeComponent parent, BoundServiceDefinition<EchoBinding> definition, DeploymentContext context) { Class<?> interfaze = definition.getServiceContract().getInterfaceClass(); return new EchoService(definition.getName(), interfaze, parent, wireService); }
protected Class<EchoBinding> getBindingType() { return EchoBinding.class; }}
Describes to the runtime which binding type the class handles
17 tu sca ny
The TargetInvoker
• Returned by Referencespublic class EchoInvoker implements TargetInvoker {
//…
public Object invokeTarget(final Object payload) throws InvocationTargetException { // echo back the result, a real binding would invoke some API for flowing the request return ((Object[])payload)[0]; }
public Message invoke(Message msg) throws InvocationRuntimeException { try { Object resp = invokeTarget(msg.getBody()); msg.setBody(resp); } catch (InvocationTargetException e) { msg.setBody(e.getCause()); } catch (Throwable e) { msg.setBody(e); } return msg; }
public Object clone() throws CloneNotSupportedException { return super.clone(); }} Describes to the runtime which binding type the class handles
18 tu sca ny
Agenda
• Overview
• Extension Types
• Creating a Binding Extension
• Advanced Tuscany Programming Model
• Creating a Component Type Extension
19 tu sca ny
The Extension Programming Model
• All components by default are module scoped (i.e. singletons within a composite)
• Wiring may be done directly as in SCA or through autowire (recommended)• Wire by contract: runtime responsible for supplying an implementation of
an interface• Checks sibiling components, then recurses upward through the component
hierarchy. If a sibling is a composite, only services exposed by it may be wired to.
• Virtually any type of extension can be supplied to the runtime this way
20 tu sca ny
An Example Component
public abstract class BindingBuilderExtension<B extends Binding> implements BindingBuilder<B> {
protected BuilderRegistry builderRegistry; protected WireService wireService;
@Autowire public void setBuilderRegistry(BuilderRegistry registry) { this.builderRegistry = registry; }
@Autowire public void setWireService(WireService wireService) { this.wireService = wireService; }
@Init(eager = true) public void init() { builderRegistry.register(getBindingType(), this); }
//…}
21 tu sca ny
An Example SCDL
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
name=”BindingSCDL">
<component name="BindingLoader"> <system:implementation.system class="echo.EchoBindingLoader"/> </component>
<component name="BindingBuilder"> <system:implementation.system class="echo.EchoBuilder"/> </component>
</composite>
22 tu sca ny
Patterns: Monitor
• Logging is externalized• Do not use commons-logging a.k.a. “clogging”, Log4J, JDK, etc.
• Instead, decorate a field, setter or constructor param with @Monitor
• Runtime will provide an implementation of the monitor interface. The implementation will delegate to a logging implementation
• Avoids memory leaks and allows for better internationalization
@Monitorpublic void setMyMonitor(MyMonitor){
// ..}
public void someMethod(){myMonitor.started(“Stated monitor”);
}
23 tu sca ny
Patterns: Registry
• Often, a registry is used which is a component that other components register with• Loaders and Builders register with a LoaderRegistry and BuilderRegistry.
The latter dispatch to the right loader or builder when a SCDL or model is being evaluated
• Eager initialization is used to register
@Autowire public void setBuilderRegistry(BuilderRegistry registry) { this.builderRegistry = registry; }
@Init(eager = true) public void init() { builderRegistry.register(getBindingType(), this); }
24 tu sca ny
Agenda
• Overview
• Extension Types
• Creating a Binding Extension
• Advanced Tuscany Programming Model
• Creating a Component Type Extension
25 tu sca ny
Creating an Atomic Component Implementation Type
1. Implement 1..n model POJOs 2. Implement Loader or extend LoaderExtension
• Reads a StAX stream and creates appropriate model objects
3. Implement AtomicComponent or extend AtomicComponentExtension• Extension will be given InboundWires and OutboundWires corresponding to its
services and references; it must decide how to inject those onto its implementation instances (e.g. create a proxy)
• A WireService will be provided to the extension, which it can use to generate proxies and WireInvocationHandlers
• The extension must implement createTargetInvoker(..) and instantiate TargetInvokers responsible for dispatching to target instances
4. Implement ComponentBuilder or extend ComponentBuilderExtension• Implements build(..) which returns the AtomicComponent implementation
5. Write a simple SCDL file and deploy into the system composite hierarchy
26 tu sca ny
Creating a Composite Component Implementation Type
1. Implement 1..n model POJOs 2. Implement Loader or extend LoaderExtension
• Reads a StAX stream and creates appropriate model objects
3. Implement CompositeComponent or extend CompositeComponentExtension• The extension must implement createTargetInvoker(..) and instantiate
TargetInvokers responsible for dispatching to target child instances
4. Implement ComponentBuilder or extend ComponentBuilderExtension• Implements build(..) which returns the AtomicComponent implementation
5. Write a simple SCDL file and deploy into the system composite hierarchy