Proteus Framework

Post on 24-Feb-2016

64 views 0 download

description

Proteus Framework. Redefining the plugin. Why a new framework?. Present approaches (e.g. OSGi ) use non-standard approaches that create too many breaking points Designing a plugin architecture for both scalability and supportability requires an extra level of design often overlooked - PowerPoint PPT Presentation

Transcript of Proteus Framework

S

Proteus FrameworkRedefining the plugin

Why a new framework?

Present approaches (e.g. OSGi) use non-standard approaches that create too many breaking points

Designing a plugin architecture for both scalability and supportability requires an extra level of design often overlooked

Few developers embrace the built-in plugin capabilities of the Java platform

Forward Compatibility

Definition: the ability of an SDK to ensure that plugins written in version n continue work without recompilation in version n+1

As the architect of a plugin-driven application, how do you guarantee forward compatibility when the plugin consumer has imported your interfaces into their binaries?

What’s wrong with OSGi?

In a word: nothing However, it may not be the right framework for

your application. Why pick Struts over Spring? Why use Spring over pure EJB? Advocates of each of these frameworks can quickly enumerate why they felt (or chose) one framework over the other.

One framework doesn't solve every problem

OSGi vs Proteus

Both embody the notion of SOA in a Virtual Machine Modularity is at the core of both designs Plugins (or Bundles, in OSGi parlance) are published, found by a

consumer dynamically at runtime, and bound in order to issue service invocation requests

OSGi relies on the MANIFEST.MF metadata to publish (export) its plugins (bundles)

Proteus relies on compiled code, Plugin Archetypes that define a class of service, and core Java SE’s Service Provider Interface (SPI) architecture

Runtime vs Compile Time

OSGi relies on "proprietary” MANIFEST.MF metadata to wire up services Googling shows just how hard time consuming it can be to

wire up existing libraries into OSGi Inherent class loader problems come along for free

Proteus adopts the standardized Java Service Provider Interface (SPI) architecture built-in to Java SE No wiring beyond declaring the factory in META-INF/services Not designed to solve the “2 versions of the same library”

problem

Comparing Coding Styles

OSGiString serviceName = Service.class.getName();ServiceReference ref = ctx.getServiceReference(serviceName); Service svc = (Service) ctx.getService(ref));svc.callSomeMethod();

ProteusINamespace ns = new Namespace(“com.foo”, “Bar”);IPluginRegistrar pluginRegistrar = delegate.getPluginRegistrar(ns);MyService svc = pluginRegistrar.createPlugin(new Version(1), MyService.class);svc.callSomeMethod();

Breaking Dependencies

Instead of the plugin consumer directly importing the plugins actual interface, the plugin consumer needs to import a proxy that represents a specific version of a plugin interface. Java includes native support for dynamic proxy objects!

Plugin consumer achieves compile type type checking, but they do so by compiling against a specific version of a proxy interface instead of the actual physical interface used by the actual plugin Look at the last slide again- notice the explicit version request of

a proxy interface, 1.0 of MyService.

GoF Interface Development

Develop against an interface, not an implementation

Proteus, like OSGi, forces the developer to embrace this fundamental tenant of object oriented development

Plugin Archetype is a physical construct that drives interface over implementation development at the plugin level Comprised of a namespace and a set of versioned interfaces Typically deployed in a single .jar file Plugin Archetype = Category of Plugin

Versions: First Class Citizens

Semantic Versioning http://semver.org Major.Minor.Patch Versions must increase over time

Minor version may include new, backwards compatible functionality 1.0 is forward compatible with 1.1 1.1 is not backward compatible with 1.0

Patch level is never considered when determining version compatibility Patches must not introduce new functionality, only bug fixes!

All Proteus plugin access includes an explicit version reference

Triple-Bonded Factory Design

Proteus Factory Registrar is the master registrar that manages one or more Plugin Archetypes

Each Plugin Archetype maintains its own Plugin Registrar that manages one or more concrete implementations of the archetype.

The Plugin Registrar is a factory that can create instances of a specific version and/or instance of the plugin archetypeProteus Factory Registrar Plugin Registrar Plugin

Instance

Proteus Factory Registrar

Entry point into the Proteus plugin architecture Registrar is solely responsible for being the

authoritative registrar for all known Plugin Archetypes

Access to the Proteus Factory Registrar is implicit through an injected delegate:

IPluginRegistrar pluginRegistrar = delegate.getPluginRegistrar(NAMESPACE);

a priori Archetype Knowledge

Applications must have a priori knowledge of the plugin archetypes they intend to support

Application is designed against a specific archetype interface version Remember, archetype is defined by a namespace and version

Java SE Service Provider Interface ServiceLoader architecture used to dynamically locate and enumerate plugin archetypes instances Archetypes are declared in the .jar manifest according to Java SE by

defining their fully qualified class within a text file defined by Java SE SPI architeture:

META-INF/services/org.proteusframework.spi.ProteusRegistrarFactory

Plugin Registrar

Plugin Registrar is the authoritative registrar for a specific Plugin Archetype.

Specific plugin instances can be be created by version

Proteus embraces Java GenericsVersion ver = new Version(1);MyInterface plugin =

pluginRegistrar.createPlugin(ver, MyInterface.class);

Dynamic Plugin Discovery

Plugin Archetypes require a priori knowledge programmed into the application

Concrete instances of a plugin archetype have no such requirement; discovered dynamically by Java SE by searching the CLASSPATH for .jar manifest entries

META-INF/services/org.proteusframework.pluigin.spi.MyPlugin

Plugin Architecture Review

The Proteus Factory Registrar manages a collection of Plugin Archetypes

A Plugin Archetype Registrar Factory creates a singular Plugin Registrar

A Plugin Registrar manages a collection of homogenous Plugin Instances

A Plugin Instance provides a specific configurable concrete plugin

Defining a Plugin Archetype

Archetype Package Structure

Interfaces Defines one or more versions of a plugin’s interface

Registrar Plugin Archetype Registrar Factory that collects concrete instances of the

archetype and stands ready to instantiate specific plugin implementation versions SPI

Abstract plugin factory extended by concrete instances Plugin Archetype Registrar Factory delegates construction of the plugin instance

here META-INF/services

How a plugin archetype is declared within a Proteus Application

Archetype Definition

By and large boilerplate code Anticipate implement a mvn plugin so that a plugin can

be created via mvn archetype:archetype command Decide on a namespace Implement one or more plugin interface versions Link the interfaces to semantic versions within the

VersionCollection

Concrete Plugin Structure

Plugin Factory Implementation

Version Implementation

Proxy Interface unused by concrete plugin implementations Concrete plugin extends the actual version interface; the

plugin instance is explicitly dependent upon the Plugin Archetype .jar

public class Version1Impl extends AbstractStandardPlugin implements ISampleVersion1

Specific Version Each plugin is tied to a specific version explicitly be the

versioned interface it implements from the plugin archetype

Bootstrap a Proteus Application

Create a main class that extends AbstractRuntimeEnginepublic class SampleApplication extends AbstractRuntimeEngine

Create an instance of either a StandardProteusApplication or ExtendedProteusApplication

IProteusApplication myApplication = new StandardProteusApplication();

Instantiate the runtime engine IRuntimeEngine myRuntimeEngine = new SampleApplication();

Bootstrap a Proteus Application

Inject the runtime engine into the application myApplication.setRuntimeEngine(myRuntimeEngine);

Start the applicationmyApplication.startApplication();

Formally launch the application in the run() methodpublic void run() {runningFlag = true; ... }

Application Configuration

Standard Proteus applications can easily separate out their configuration from the actual runtime implementation

Use of IConfigurationLoader provides an abstraction on IProteusApplication between configuration and storage Java SE deployment will differ from an Android

deployment

Plugin Instantiation

Get version 1 interface from the default plugin provider Default can be defined during runtime engine

configuration (e.g. .properties file)

MyExpectedVersion1Interface example1 = pluginRegistrar.createPlugin(new Version(1),

MyExpectedVersion1Interface.class);

Plugin Instantiation

Get version 1 interface from a specific concrete plugin

INamespace pluginNS = new Namespace(”com.foo", “FooRegistrar");IVersionDescriptor vd = new VersionDescriptor(pluginNS, new Version(1, 0));

MyVersion1Interface example2 = pluginRegistrar.createPlugin(vd, MyVersion1Interface.class);

Application Shutdown

Resource cleanup requires that the engine be shutdown propertly Accomplished with a single call:

myApplication.stopApplication();