Presentation is loading. Please wait.

Presentation is loading. Please wait.

CBSE Concepts – Short review “A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only.

Similar presentations


Presentation on theme: "CBSE Concepts – Short review “A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only."— Presentation transcript:

1 CBSE Concepts – Short review “A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software component can be deployed independently and is subject to composition by third-parties.” (Szyperski)

2 CBSE Concepts – Short review Modeling components with UML: component diagrams, components, provided and required interfaces, ports, connectors

3 CBSE Concepts – Short review

4 CBSE concepts – Short review Component Component platform (component framework) Operating System Middleware Hardware Platform Services: allow components written according to the model to communicate; locating, linking, replacing components Horizontal Services: application-independent services used by different components. Concurrency, security, transaction management, Resource management

5 CBSE – Lectures 4+5 Component models: Case study: OpenCom – OpenCOM is a leightweight and reflective component model – Developed by The Next Generation Middleware group at Lancaster University http://www.comp.lancs.ac.uk/computing/research/mpg/reflection/software.htm – Used as a development and distribution environment for many research systems. Adaptive middleware: OpenORB

6 OpenCom Versions: – OpenCOM v1: built on top of Microsoft COM and has been successfully applied to constructing re-configurable middleware platforms. The main limitation is its inability to construct systems for a heterogeneous environment High memory footprint Component model is In-process – OpenCom: independent of Microsoft COM Small memory footprint, also usable for mobile and embedded devices OpenCOM v1 implementation in C – http://sourceforge.net/projects/opencomc/ http://sourceforge.net/projects/opencomc/ OpenCOM v1 implementation in Java – http://sourceforge.net/projects/gridkit/ OpenCOMJv1.4.zip http://sourceforge.net/projects/gridkit/ – OpenCOM v2 (also independent of COM) Components can be in different address spaces

7 Basic concepts in OpenCOM The fundamental concepts in OpenCOM are: interfaces, receptacles and connections. – For example, if a component requires a service S, it would declare a receptacle of type S which would be connected at run-time to an external interface instance of type S (which would be provided by some other component). A binding is a run-time association between a single interface and a single receptacle. – Interfaces may participate in multiple bindings, whereas each receptacle may only participate in a single binding at a time. – Like component deployment, the creation of bindings is inherently third-party in nature. That is, bindings can be created by any component, not only by the ‘first-party’ components whose interface or receptacle is actually participating in the binding OpenCOM is a lightweight and efficient in-process component model – In OpenCOM v1 all components that build a system must be in the same address space

8 OpenCOM Runtime OpenCOM deploys a standard runtime substrate per address space Functions of the OpenCOM runtime substrate (kernel): – manages the creation and deletion of components – acts upon requests to connect/disconnect components – maintains a system graph of the components currently in use The explicit maintenance of dynamic dependencies between components provides the support for introspection and reconfiguration of component configurations. The reflective interfaces of OpenCOM follow three of the meta-models proposed by OpenORB i.e. the Interface meta-model (IMetaInterface), the Architecture meta-model (IMetaArchitecture) and the Behaviour meta-model (IMetaInterception).meta-models proposed by OpenORB Implementation: – V1: uses the core features of Microsoft COM to underpin its implementation; these include the binary level interoperability standard, Microsoft's IDL, COM's globally unique identifiers and the IUnknown interface. The higher-level features of COM, including distribution, persistence, transactions and security are not used. – OpenCom: does not rely on COM, is very lightweight

9 The architecture of OpenCOM

10 Reflection Reflection is the capability of a system to reason about and act upon itself A reflective system provides (at least) two linked interfaces to its clients: – a base-level interface to the system’s functionality similar to the interface of other such systems – a meta-level interface that reveals aspects of how the base-level interface is implemented Why reflection: – Suport for introspection The ability to inspect the structure and behaviour of the system – dynamic monitoring, debugging – Suport for adaptation by intercession Runtime reconfiguration OpenCOM uses 3 orthogonal reflective meta-models These allow both structural reflection and behavioral reflection – Structural reflection is the representation of (static) structure of the system – Behavioural reflection is the representation of ongoing activity

11 Structural reflection in OpenCOM The interface meta-model (IMetaInterface – reflective interface of every OpenCOM component) – Supports introspection on the external representation of a component Dynamically discover interfaces/receptacles of a component Dynamically invoke discovered interfaces capability similar to introspection facilities in the Java reflection API Introspection only (no adaptation): programmer cannot modify interfaces (add new method) or access implementations The architecture meta-model (IMetaArchitecture – reflective interface of the OpenCOM kernel) – Supports introspection and adaptation of the underlying software architecture Software architecture = component graph

12 Behavioural reflection in OpenCOM The interception meta model (IMetaInterception – reflective interface of the kernel) – Supports the interception of pre- and post- methods on a given interface – Lightweight means of adding new behaviour – Does not require the reconfiguration of the existing component architecture

13 OpenCOM components Every OpenCOM component implements the following standard interfaces: – ILifeCycle provides operations called startup and shutdown that are called when a component is created or destroyed. – IConnections(optional – previously called IReceptacles) offers methods to modify the interfaces connected to a component's receptacles. These are only called by the OpenCOM runtime component. A component without receptacles does not implement this interface. – IMetaInterface supports inspection of the types of interfaces and receptacles declared by the component. The meta information to support these operations is stored in the type library of each component. – IUnknown is equivalent to the interface with the same name in Microsoft COM. It is used to get the reference to the requested interface on that component instance Additionally, a component may implement also a number of custom interfaces and require a number of custom receptacles

14 OpenCOM runtime kernel A singleton in the address space of the system Reflective interfaces: – IMetaArchitecture – IMetaInterception Interface for the kernel API: IOpenCOM – createInstance – deleteInstance – Disconnect – Connect – getComponentName – getComponentPIUnknown – getComponentCLSID – isContained

15 OpenCom composite components Composite components: a structuring mechanisms to develop complex component-based applications OpenCOM provides no kernel-level support for creating composite components Composites can be created by the user according to a general model Composite components are called in the OpenCOM terminology “ComponentFrameworks” ! In OpenCom, a component framework (CF) is a tightly coupled set of components that – cooperates to address some focused area of concern; – provides a well-defined extension protocol that accepts additional “plug- in” components that modify or extend the CF’s behavior; – constrains how these plug-ins may be organized.

16 OpenCom composite components Actually called ICFMetaInterface In the OpenComJ API

17 OpenCOM composite components The design of this component framework model is based upon the concept of composite components and promotes the following key properties: – A component framework in OpenCOM is a composite OpenCOM component Therefore, component frameworks in OpenCOM are implemented as OpenCOM components; that is, they implement the same base interfaces (IMetaInterface, ILifeCycle and IConnections), custom service interfaces and receptacles. – A component framework provides an additional meta-interface ICFMetaArchitecture (ICFMetaInterface in the OpenComJ API) for inspection and dynamic adaptation of the local architecture of the composite component. To be subject to introspection and dynamic reconfiguration, each component framework maintains a local graph of its internal structure. To reduce data duplication, this is simply a view of the information held in the OpenCOM system graph. Therefore, each CF maintains a list of Component Identifiers that point to their corresponding position in the system graph. – The integrity of each component framework is maintained in the face of dynamic change, using developer specified architectural rules plugged into the component framework. Each component framework provides a receptacle named IAccept into which developers can plug their own checking implementation. this consists of a single operation that takes as parameters the local graph of the component framework and the list of interfaces that expose the structure’s functionality. When executed it returns a Boolean value to indicate if the structure is valid; if true, the component framework continues its operation. Otherwise, if false, the component framework rolls back to the previous known good configuration (stored prior to the change) and generates a message to indicate a failed reconfiguration.

18 OpenCOM v2 OpenCOMv2: to support systems that span multiple deployment environments, and can be used to develop platforms that combine multiple target domains. Adds Platform Extensions: augment the basic programming model with new optional abstractions and services – Capsules, Caplets, Loaders and Binders

19 OpenCOM v2 Adds capsules, caplets, loaders and binders Capsules are containing entities into which components are loaded, instantiated and composed. Each capsule defines a name space for its contained component instances (hereafter, we refer to component instances simply as ‘components’), and offers the OpenCom kernel API Capsules are “component containers” that may encompass multiple address spaces and are managed by one single kernel. They provide a namespace in which all components and interfaces are individually identified by a unique identifier. Each capsule is associated with one specific OpenCom kernel that is responsible for deploying components in that particular capsule. Usually, an entire system will reside in one capsule. The notion of capsule helps reason about cases where multiple kernels must interact (for legacy or compatibility reasons, for instance).

20 Caplets-Loaders-Binders Caplets are OpenCom’s representation of a “locus of deployment”. Conceptually, caplets allow the kernel to support different technologies in the underlying deploying environment. They also provide an isolation mechanism between components which are mutually distrustful or have different privileges. For example, if a system requires deployment of both C++ and Java components, this can be achieved by creating separate caplets for each technology domain. Note that caplets and capsules differ in that caplets are explicitly created, unlike the capsule associated with each kernel. In this respect, a capsule should be regarded a logical component containers that may encompass several address spaces and hardware domains and may therefore contain several caplets. Loaders encapsulate the complexity of loading components in a heterogeneous environment. Each loader supports a specific loading mechanisms, thus allowing a wide range of component styles to be managed by the same kernel. Binders are OpenCom components designed to provide a wide range of ‘binding mechanisms’. Using binders, developers are free to implement any binding mechanism that might be required in the underlying deployment environment. For example, they may implement a binder that creates connections between Java components or a binder that connects components written in Assembly language When the kernel starts, it only contains a single caplet, the primary caplet. At this point the caplet coincides with the enclosing capsule. Additional caplets termed extension caplets may then be progressively added to the system through the extensions framework to support new styles of components.

21 Caplets-Loaders-Binders The kernel is only capable of deploying primary-style components. From an implementation point of view, caplets, loaders and binders are primary-style components and are deployed by the kernel. They provide a bridge to a new deployment environment

22 References OpenCOM page: http://www.comp.lancs.ac.uk/computing/research/mpg/reflection/software.htm http://www.comp.lancs.ac.uk/computing/research/mpg/reflection/software.htm [OpenCOMv1] Clarke, M., Blair, G. S., Coulson, G., and Parlavantzas, N. 2001. An Efficient Component Model for the Construction of Adaptive Middleware. In Proceedings of the IFIP/ACM international Conference on Distributed Systems Platforms Heidelberg (November 12 - 16, 2001). R. Guerraoui, Ed. Lecture Notes In Computer Science, vol. 2218. Springer- Verlag, London, 160-178. [OpenCOMv2] Coulson, G., Blair, G., Grace, P., Taiani, F., Joolia, A., Lee, K., Ueyama, J., and Sivaharan, T. 2008. A generic component model for building systems software. ACM Trans. Comput. Syst. 26, 1 (Feb. 2008), 1-42. DOI=http://doi.acm.org/10.1145/1328671.1328672 Note: these articles present the general concepts of OpenCOM. They are NOT an accurate description/documentation of the current API ! – [OpenCOMv1] includes some details that are outdated – [OpenCOMv2] discusses the API in a simplified form for presentation purposes

23 OpenComJ OpenCOM v1 implementation in Java Available at: – http://sourceforge.net/projects/gridkit/ http://sourceforge.net/projects/gridkit/ – To use OpenCOM you need to download: opencomjv1.4.zip Documents > OpenCOMJHandbook.pdfOpenCOMJHandbook.pdf

24 The OpenCom Java component specification Each component is made up from a set of Java classes. One class from this set defines the component type; we refer to this as the foundation OpenCOMJ class. For example, a component of type A includes a foundation class named A. The foundation class must implement a set of OpenCOM specific interfaces: – IMetaInterface – ILifeCycle – IUnknown The component must be third party deployable; hence each component must be available within a JAR; a single JAR can contain one or more OpenCOMJ components. Each OpenCOMJ component lists one or more provides interfaces. Each interface must be an OpenCOM interface, which inherits the IUnknown interface. – This is opposed to a Java interface (although Java interfaces can still be used in component implementation classes they cannot be used to connect components together, or be queried by IUnknown). An OpenCOMJ component optionally lists a set of required interfaces. This consists as a set of receptacles (that must inherit from the OCM_Receptacle class). Each receptacle is a publicly accessible field of the foundation class. Apart from receptacles, no java field must be publicly accessible from classes external to the component classes. A composite component or component framework must implement the ICFMetaInterface interface, and define a single receptacle of type IAccept.

25 Developing a basic OpenCOM component Example: Adder IAdd Component Adder provides Interface IAdd

26 Developing a basic OpenCOM component Step 1. Define your provides interfaces package Samples.AdderComponent; import OpenCOM.*; public interface IAdd extends IUnknown{ /** * Add two integers together. * @param x Operand X. * @param y Operand Y. * @return The added values. */ public int add(int x, int y); } To create an OpenCOMJ interface you create a Java interface class that extends the IUnknown interface from OpenCOM.

27 Developing a basic OpenCOM component Step 2. Create the foundation class package Samples.AdderComponent; import OpenCOM.*; public class Adder extends OpenCOMComponent implements IAdd, IUnknown, IMetaInterface, ILifeCycle { /** Creates a new instance of Adder */ public Adder (IUnknown pRuntime) { super(pRuntime); }... } 1.create a new Java class with the same name as the type of component you wish to create 2.The foundation class extends the OpenCOMComponent abstract class. 3.The foundation class constructor must have the following syntax: classname(IUnknown) 4. The foundation class must implement three interfaces: IUnknown, IMetaInterface, and ILifeCycle

28 Developing a basic OpenCOM component Step 3. Implementing ILifeCycle in the foundation class // ILifeCycle Interface Implementation public boolean shutdown() { System.out.println(“Stopping Component”); return true; } public boolean startup(Object pIOCM) { System.out.println(“Starting Component”); return true; } Of the three standard interfaces, you only need to write operation implementations for ILifeCycle, as the others are implemented within the abstract class. This is because you place the application specific code you want to execute when the component is started (not constructed), and when it is stopped. Hence, you can create components that are executable over time

29 Developing a basic OpenCOM component Step 4. Implementing the provides interface in the foundation class /** * Add two integers together. * @param a Operand X. * @param b Operand Y. * @return The added values. */ public int add(int a, int b) { return a+b; }

30 Developing an OpenCOM component with receptacles Example Calculator ICalculator IAdd Component Calculator provides Interface ICalculator and requires Interface IAdd

31 Developing an OpenCOM component with receptacles Step 1. Defining the receptacle interface Samples.AdderComponent.IAdd For each component interface you require to bind to another component, you must implement the corresponding OpenCOM interface class. Although this will typically already have been implemented in creating the provides interface

32 Developing an OpenCOM component with receptacles Step 2. Adding the IConnections interface to the component implementation public class Calculator extends OpenCOMComponent implements ICalculator, IConnections, ILifeCycle, IUnknown, IMetaInterface { When there are receptacles to be connected a component must implement the OpenCOM IConnections interface in addition to the other core OpenCOM interfaces. Hence, we add it to the implements list of the foundation class

33 Developing an OpenCOM component with receptacles Step 3. Creating the receptacles import OpenCOM.*; import java.util.*; // Interfaces import Samples.AdderComponent.IAdd; public class Calculator extends OpenCOMComponent implements ICalculator, IConnections, ILifeCycle, IUnknown, IMetaInterface { /** * Requires Interface of type IAdd. */ public OCM_SingleReceptacle m_PSR_IAdd; /** Creates a new instance of Calculator */ public Calculator(IUnknown binder) { super(binder); // Initiate the receptacles m_PSR_IAdd = new OCM_SingleReceptacle (IAdd.class); } To define your receptacles in the foundation class you list the receptacles as public fields of the foundation class. Then construct the receptacles within the component constructor

34 Developing an OpenCOM component with receptacles Step 4. Implementing the IConnections interface // IConnections Interface public boolean connect(IUnknown pSink, String riid, long ConnID) { if(riid.toString().equalsIgnoreCase("Samples.AdderComponent.IAdd")){ return m_PSR_IAdd.connectToRecp(pSinkIntf, riid, provConnID); } return false; } public boolean disconnect(String riid, long connID) { if(riid.toString().equalsIgnoreCase("Samples.AdderComponent.IAdd")){ return m_PSR_IAdd.disconnectFromRecp(connID); } return false; } The IConnections interface must be implemented following a consistent syntax to ensure that your components are connected correctly For each of the receptacles check if the riid parameter matches the type of the receptacle; if it does, either call connectToRecp on the receptacle or disconnectFromRecp

35 Developing an OpenCOM component with receptacles Step 5. Invoking a Receptacle //Interface ICalculator implementation /** * Add two integers together. * @param a Operand X. * @param b Operand Y. * @return The added values. */ Public add (int a, int b) { /* * Standard single receptacle invocation. */ return m_PSR_IAdd.m_pIntf.add(a, b); } In order to use another component’s provided functionality, you invoke a connected receptacle. To do this you call the method name from the interface on the receptacle.m_pIntf field of your receptacle. For example, here we wish to call add on the adder component, therefore we call the add operation preceded by m_PSR_IAdd.m_pIntf. The add operation of the ICalculator interface has nothing to do with the add operation of the IAdd interface !

36 Creating Systems with OpenCOM components Example Calculator ICalculator IAdd Adder OpenCOM IOpenCOM

37 Creating Systems with OpenCOM components 1.Creating the Runtime Kernel // Create the OpenCOM runtime & Get the IOpenCOM interface reference OpenCOM runtime = new OpenCOM(); IOpenCOM pIOC=(IOpenCOM) runtime.QueryInterface("OpenCOM.IOpenCOM"); To use OpenCOM you must create an instance of the kernel in the local jvm address space. The second line displays an important programming procedure in OpenCOMJ known as QueryInterface. Every component (and the runtime) has an IUnknown interface with a single operation: QueryInterface. This operation allows you to get a reference to the interface you wish to invoke operations on. Here, we want to use the core IOpenCOM interface therefore, we query from the runtime the interface type: “OpenCOM.IOpenCOM” and this returns a java reference, or null if the interface isn’t available on this element

38 Creating Systems with OpenCOM components 2.Creating a new Component Instance // Create the Adder component IUnknown pAdderIUnk = (IUnknown) pIOCM.createInstance (“Samples.AdderComponent.Adder”, “Adder”); ILifeCycle pILife = (ILifeCycle) pAdderIUnk.QueryInterface(“OpenCOM.ILifeCycle”); pILife.startup(pIOCM); To create a new component you use the createInstance operation on the previous IOpenCOM interface reference. Note, you are returned an IUnknown reference of the Component (or null); this uniquely identifies the component in the address space and can be used to find further interfaces. If the component needs to begin executing you call the startup operation on the ILifeCycle interface. When this is done is dependent on the component. If there is no execution then you don’t need to call it. You may also want to wait until the component is fully connected. To startup you perform QueryInterface on the new component reference and then invoke startup. The parameter of startup can be any object, so you can pass any specific information to a component at this point in time. The example passes the runtime reference as a parameter for illustrative purposes only.

39 Creating Systems with OpenCOM components 3.Connecting two components long ConnID1 = pIOCM.connect(pCalcIUnk, pAdderIUnk, "Samples.AdderComponent.IAdd"); Components with required interfaces need to be connected, otherwise their operations will fail when called. In our example, the calculator component must be connected to the adder component on the IAdd interface. Therefore, after first creating an instance of each of the two components we connect them together using the connect operation from IOpenCOM. Connect has following parameters: Param1: The reference of the component with the receptacle to connect Param 2: The reference of the component with the interface to connect. Param 3: The class type of the interface to connect Return: A positive long reference uniquely identifying the connection. Every connection gets a unique reference (that is valid for the lifetime of the kernel operation). –1 is returned if the connection failed.

40 Creating Systems with OpenCOM components 4.Disconnecting two components pIOCM.disconnect(ConnID1); To disconnect two components you invoke the disconnect operation from IOpenCOM; you pass the previously stored reference number of the connection as a parameter.

41 Creating Systems with OpenCOM components 4.Deleting a component pIOCM.deleteInstance(pAdderIUnk); To delete a previously created component instance you use the deleteInstance operation from the IOpenCOM interface. This will safely shutdown and disconnect the component (if you haven’t already done it) and remove the instance from the meta-level information. However, because the component is implemented in Java it may not be removed from memory immediately

42 Performing reflective operations Example Calculator ICalculator IAdd Adder OpenCOM IOpenCOM IMetaArchitecture IMetaInterception IMetaInterface

43 Performing reflective operations 1.Architecture meta model operations The architecture meta-model allows you to discover the architecture of components in terms of what components are connected to another. For this there are two operations that are available from the IMetaArchitecture interface that is provided by the OpenCOM runtime: – enumConnsToIntf examines a particular interface of a component and then describes who is connected to that interface. – enumConnsFromRecp examines a particular receptacle and then describes – These operations give us a vector of connection identifiers. – Next, we can use each long identifier from the list, calling getConnectionInfo() from the IOpenCOM interface to find out the information about this connection

44 Performing reflective operations 1.Architecture meta model operations - Example IMetaArchitecture pIMetaArch = (IMetaArchitecture) runtime.QueryInterface("OpenCOM.IMetaArchitecture"); Vector list = new Vector (); int NoConns = pIMetaArch.enumConnsToIntf(pAdderIUnk, "Samples.AdderComponent.IAdd", list); for(int index=0; index<NoConns; index++){ OCM_ConnInfo_t TempConnInfo = pIOCM.getConnectionInfo(list.get(index).longValue()); System.out.println("Component "+ TempConnInfo.sinkComponentName + " is connected to " + TempConnInfo.sourceComponentName + " on interface " + TempConnInfo.interfaceType); }

45 Performing reflective operations 2.Interface meta model operations this meta model differs in that you interact with the components via their IMetaInterface rather than the run-time kernel to get information. The Interface meta model allows you to: – inspect the interfaces and receptacles available on components enumIntfs and enumRecps – add and inspect meta-data that has been attached to interface elements (i.e. instances of a receptacle or interface). you can add information in the form of a name-value pair to either an individual interface element or a receptacle element of a component setAttributeValue and GetAttributeValue

46 Performing reflective operations 2.Interface meta model operations - Example IMetaInterface pMeta = (IMetaInterface) pAdderIUnk.QueryInterface("OpenCOM.IMetaInterface"); Vector ppIntf = new Vector (); int length = pMeta.enumIntfs( ppIntf); System.out.println("The number of Interfaces on Adder component is"+length); for (int y=0; y<length; y++){ Class temp = ppIntf.elementAt(y); System.out.println(temp.toString()); } IMetaInterface pMeta = (IMetaInterface) pAdderIUnk.QueryInterface("OpenCOM.IMetaInterface"); pMeta.SetAttributeValue("Samples.AdderComponent.IAdd", "Interface", "Variation", "int", new Integer(8));

47 Performing reflective operations 3.The Interception meta model The interception meta model is an important feature of OpenCOMJ, as it allows you to add new behaviour to a running system dynamically. It does this by allowing you to add pre- and post- interceptors to any interface of an OpenCOM component. 2 phases: – write a new interceptor – add interceptor to an interface instance.

48 Performing reflective operations 3. Interceptions meta model operations – Example: write a new pre interceptor Public class PreAndPostMethods { … public int Pre0(String method, Object[] args){ // Take 8 off the first integer parameter // to correct the addition Integer int1 = (Integer) args[1]; int val = int1.intValue()-8; args[1] = new Integer(val); return 0; } … } An interceptor is a Java method that follows a particular syntax that allows it to be used in the interception meta model. The String “method” parameter contains the name of the method that is being ‘actually’ called on the interface. Typically you can use this to determine which behaviour to use e.g. block all operations of a particular method name, or perform behaviour on one method type, and alternative behaviour on another method. The “Object[] args” parameter contains the list of parameters of the operations for the real method call.

49 Performing reflective operations 3. Interceptions meta model operations – Example : add pre interceptor // Query the IMetaInterception interface from the runtime kernel IMetaInterception pIMeta = (IMetaInterception) runtime.QueryInterface("OpenCOM.IMetaInterception"); //Use IMetaInterception to Get the Delegator for the required interface. We //call GetDelegator() passing the component reference and the interface type //which pinpoints the correct interface and returns the IDelegator interface //to allow you to manipulate the delegator IDelegator pIAdderDel = pIMeta.GetDelegator(pAdderIUnk, "Samples.AdderComponent.IAdd"); // Instantiate an object that hosts the interceptor method PreAndPostMethods Interceptors = new PreAndPostMethods(pIOCM); //Call AddPreMethod/AddPostMethod on the IDelegator interface. You //always pass the object where the interceptor is hosted and the name of the //interceptor pIAdderDel.addPreMethod(Interceptors, "Pre0");

50 Performing reflective operations 3. Interceptions meta model operations – Operations available on the Delegator interface AddPreMethod(Object, String) adds pre methods DelPreMethod(String) Remove the named pre-interceptor AddPostMethod(Object, String) Same procedure as AddPreMethod but this adds post methods DelPostMethod(String) Remove the named post-interceptor ViewPreMethods(String[]) Fills the string list parameter with the names of pre methods attached to this interface delegator. ViewPostMethods(String[]) Fills the string list parameter with the names of post methods attached to this interface delegator.

51 OpenCOM Implementation detail Uses the Java dynamic proxy mechanism Delegator

52 Proxy pattern

53 Classical Proxy Implementation vs Dynamic Proxy A Classical Proxy Implementation requires the Programmer to write the code of the Proxy class for every Original Interface and compile it. A dynamic proxy class is a class that implements a list of interfaces specified at runtime when the class is created

54 Java dynamic proxy A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. Thus, a dynamic proxy class can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class, such as with compile-time tools. Method invocations on an instance of a dynamic proxy class are dispatched to a single method in the instance's invocation handler, and they are encoded with a java.lang.reflect.Method object identifying the method that was invoked and an array of type Object containing the arguments. This process allows implementations to "intercept" method calls and reroute them or add functionality dynamically. The dynamic proxy can act as a Decorator pattern, where the proxy wraps invocations with additional functionality => it is the case with OpenCOM Delegator

55 Java dynamic proxy To read more about java dynamic proxy: Sun: http://java.sun.com/j2se/1.4.2/docs/guide/reflection/proxy.htmlhttp://java.sun.com/j2se/1.4.2/docs/guide/reflection/proxy.html IBM technical library: http://www.ibm.com/developerworks/java/library/j-jtp08305.htmlhttp://www.ibm.com/developerworks/java/library/j-jtp08305.html Java Reflection in Action: http://www.webreference.com/internet/reflection/http://www.webreference.com/internet/reflection/

56 Proxy object – an instance of the dynamic proxy class created automatically at runtime The service of the original Object is called by Reflection

57 Creating a dynamic proxy in Java To create a proxy for some interface Foo: InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); Foo f = (Foo) proxyClass. getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below. A proxy interface is such an interface that is implemented by a proxy class. A proxy instance is an instance of a proxy class. The unqualified name of a proxy class is unspecified. The space of class names that begin with the string "$Proxy" should be, however, reserved for proxy classes. A proxy class extends java.lang.reflect.Proxy. A proxy class implements exactly the interfaces specified at its creation, in the same order.

58 Creating a dynamic proxy in Java A shorter way to create a proxy instance for Foo: InvocationHandler handler = new MyInvocationHandler(...); Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, handler); Used in OpenCOM.Delegator: /** The dynamic proxy creation operation - takes the original component and wraps the dynamic invocation handler around it. (Delegator implements InvocationHandler) */ public static Object newInstance(Object obj) { Object ParentObject= java.lang.reflect.Proxy.newProxyInstance( obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), (java.lang.reflect.InvocationHandler) ThisObject); return ParentObject; }

59 Example: OpenCOM Delegates and Dynamic Proxies // Create the Adder component // this creates the original Adder object, the Delegator and the Proxy // returns the created proxy instance – the returned object is of type $Proxy0 IUnknown pAdderIUnk = (IUnknown) pIOCM.createInstance (“Samples.AdderComponent.Adder”, “Adder”); // Insert here code that adds Pre0 interceptor to Iadd of Adder // … see slide before // The interceptor method is stored in the Delegator // Get the Add Interface // actually gets the Proxy IAdd pIAdd = (IAdd) pAdderIUnk.QueryInterface("Samples.AdderComponent.IAdd"); //Use the Adder component // actually uses the Proxy, that uses the Delegator as InvocationHandler pIAdd.add(2,3);

60 OpenCOM Delegates Sequence diagram for example

61 pIAdd:$Proxy0:Delegator:Adder main gets pIAdd:$Proxy0 by QueryInterface

62 Alternative Receptacles IReceptacles: Interface implemented by receptacles. Provides operations to manipulate the receptacles themselves: connect and disconnect them, add meta-data to them OCM_Receptacle: abstract class OCM_SingleReceptacle – By default, simple receptacles have following limitations: – Only one interface can be connected to a receptacle – A component cannot have several receptacles of the same type – You can add several receptacles of the same type, but the problem is that you cannot differentiate them when creating a connection (or you have to do a bit of hacking around) Alternative receptacles: – OCM_MultiReceptacleParallel – OCM_MultiReceptacle – OCM_ReceptacleDynamicContext

63 Alternative Receptacles 1.Parallel Receptacle OCM_MultiReceptacleParallel Calculator IOutput Adder Multiple components all implementing the same interface type can be connected to this receptacle. The example shows 3 adder components that are connected to the calculator receptacle of type IOutput. When the receptacle is invoked, each connection executes in a separate thread. Important: there are no return values; hence only void methods are appropriate.

64 Alternative Receptacles 1.Parallel Receptacle - Example // changes in the foundation class (CalculatorParallel) // define the receptacle as a public field of the component public OCM_MultiReceptacleParallel m_PSR_IOutput; //initialise it within the constructor m_PSR_IOutput = new OCM_MultiReceptacleParallel (IOutput.class); // invoke operation on receptacle – in parallel ! m_PSR_IOutput.m_pIntf.DisplayMessage(message); // changes in the test program // Create the Adders for(int i=0; i<10; i++){ pAdderIUnk = (IUnknown) pIOCM.createInstance("Samples.AdderComponent.Adder", "Adder "+i); long ConnID3 = runtime.connect(pCalcIUnk, pAdderIUnk, "Samples.AdderComponent.IOutput"); }

65 Alternative Receptacles 1.Parallel Receptacle – How it is implemented public class OCM_MultiReceptacleParallel extends OCM_Receptacle implements IReceptacle{ /** Type of Receptacle */ public InterfaceType m_pIntf; /** List of interface pointers this receptacle is connected to. */ private Vector interfaceList; /** List of connIDS for each connection of this receptacle. */ private Vector connIDS; private int numberOfConnections; … }

66 Alternative Receptacles 1.Parallel Receptacle – How it is implemented (cont) public class OCM_MultiReceptacleParallel extends OCM_Receptacle implements IReceptacle{ public boolean connectToRecp(IUnknown pIUnkSink, String riid, long provConnID) { // Get the reference to the component hosting the interface try{ InterfaceType pIntfRef = (InterfaceType) pIUnkSink.QueryInterface(riid); interfaceList.add(pIntfRef); } catch(ClassCastException e){ return false; } // Add info to the receptacle object stores connIDS.add(new Long( provConnID)); numberOfConnections++; return true; }

67 Alternative Receptacles 1.Parallel Receptacle – How it is implemented (cont) public class OCM_MultiReceptacleParallel extends OCM_Receptacle implements IReceptacle{ public boolean disconnectFromRecp(long connID) { // Traverse the data looking for the required connection ID for(int i = 0; i < numberOfConnections ; i++) { Long vecConnID = connIDS.elementAt(i); if(vecConnID.longValue() == connID) { // remove information about that connection numberOfConnections--; interfaceList.remove(i); connIDS.remove(i); } if(numberOfConnections ==0) { m_pIntf = null; return true; } return true; } return false; }

68 Alternative Receptacles 2. Sequential Receptacle - OCM_MultiReceptacle Calculator IDisplay Adder A sequential receptacle allows the programmer to choose any of the connections at a time and then call them. For example, they can select each one in term and then invoke an operation on it. Hence, you could keep trying until one returned the result you required.

69 Alternative Receptacles // changes in the foundation class (CalculatorSequential) // define the receptacle as a public field of the component public OCM_MultiReceptacle m_PSR_IOutput; //initialise it within the constructor m_PSR_IOutput = new OCM_MultiReceptacle (IOutput.class); // invoke operation on receptacle for(int i=0; i<m_PSR_IOutput.interfaceList.size(); i++){ m_PSR_IOutput.interfaceList.get(i).DisplayMessage(message); } 2. Sequential Receptacle - Example

70 Alternative Receptacles 3. Context Receptacle - OCM_MultiReceptacleDynamicContex Calculator IDisplay Adder Allows you to select a single connection from the set of multiple connections based upon a stated context parameter. Note, only one operation is called, and this is from the first connection that matches the context.

71 Alternative Receptacles 3.Context Receptacle - Example // changes in the foundation class (CalculatorDynamicContext) public OCM_MultiReceptacleDynamicContext m_PSR_IOutput; public String display(String msg) { String returnStr = message.concat(":: From Calculator"); // Create a context rule - our request for interface invoke ContextRule context[] = new ContextRule[1]; context[0]=new ContextRule("Owner", "Paul Grace"); // Find out which interface has such a context match int index = m_PSR_IOutput.getContext(context); //Invoke the indexed interface that matches. if(index>=0) m_PSR_IOutput.interfaceList.get(index).DisplayMessage(msg); return returnStr; }

72 Component Frameworks (Composites) In OpenCom, a component framework (CF) is a tightly coupled set of components that – cooperates to address some focused area of concern; – provides a well-defined extension protocol that accepts additional “plug- in” components that modify or extend the CF’s behavior; and – constrains how these plug-ins may be organized.

73 Component Frameworks (Composites) Calculator ICalculator IAdd Adder ICFMetaInterface IMetaInterface ILifeCycle IConnections IAccept

74 Component Frameworks (Composites) 1.Creating a new Component Framework public class CalculatorFramework extends CFMetaInterface implements ICFMetaInterface, IConnections, IMetaInterface, IUnknown, ILifeCycle{ /** Creates a new instance of CalculatorFramework */ public CalculatorFramework(IUnknown pRuntime) { super(pRuntime); } public Object QueryInterface(String InterfaceName) { // Test if its an exposed interface return QueryInterface(InterfaceName, this); } A framework must implement ICFMetaInterface – this provides the core and reflective functionality of the framework. A framework must inherit CFMetaInterface. A framework must implement the QueryInterface class. You can/should implement a component that implements IAccept that is then connected to this framework. All changes are then validated by this component.

75 Component Frameworks (Composites) 2. Reflection operations on CF Every component framework is subject to the same reflective operations as a standard OpenCOM component – The runtime IMetaArchitecture interface provides dynamic inspection of the external structure of a CF (i.e. what it is connected to) – The local IMetaInterface interface lists the interfaces and receptacles available from the CF However, no OpenCOM interface supports inspection or dynamic adaptation of the internal structure of a component framework. Therefore, every CF implements its own additional metainterface, named the ICFMetaInterface interface that consists of methods for – Introspection get_internal_components, get_Bound_Components, get_Internal_bindings – reconfiguration insert_component, remove_component, Replace_component, local_bind, break_local_bind, Expose_interface, unexpose_interface, Expose_receptacle, unexpose_receptacle, Replace_configuration, init_arch_transaction, commit_arch_transaction, Rollback_arch_transaction

76 Component Frameworks - Example //Step1: instantiate the CF like any other component IUnknown pCFIUnk = (IUnknown) pIOCM.createInstance ("Samples.CalculatorFramework.CalculatorFramework", "Framework"); ILifeCycle pILife = (ILifeCycle) pCFIUnk.QueryInterface("OpenCOM.ILifeCycle"); pILife.startup(pIOCM); //Step2: Create the checking component for the framework IUnknown pAcceptIUnk = (IUnknown) pIOCM.createInstance ("Samples.AcceptComponent.Accept", "Accept"); pILife=(ILifeCycle)pAcceptIUnk.QueryInterface("OpenCOM.ILifeCycle"); pILife.startup(pIOCM); // Connect the checking component to the framework long cID = pIOCM.connect(pCFIUnk, pAcceptIUnk, "OpenCOM.IAccept"); //Step3: get the reference to the ICFMetaInterface ICFMetaInterface pCF = (ICFMetaInterface) pCFIUnk.QueryInterface("OpenCOM.ICFMetaInterface");

77 Component Frameworks – Example cont // Step 4 – begin a reconfiguration – initiate a transaction, this tells the // framework to set itself in a quiescent state pCF.init_arch_transaction(); // Step 5 = create the internal configuration IUnknown pAdd = pCF.create_component("Samples.AdderComponent.Adder", "Adder"); IUnknown pCal = pCF.create_component("Samples.CalculatorComponent.Calculator", "Calculator"); // Connect the local components long connid = pCF.local_bind(pCal, pAdd, "Samples.AdderComponent.IAdd"); // Step 6 – Expose an interface pCF.expose_interface("Samples.CalculatorComponent.ICalculator", pCal); // Step 7 – Finish reconfiguration boolean success = pCF.commit_arch_transaction(); //Step 8 – Using the Framework as a standard component pICalc = (ICalculator) pCFIUnk.QueryInterface( "Samples.CalculatorComponent.ICalculator"); // test the Add System.out.println("The value of 18+19 = "+ pICalc.add(18,19));

78 Component Frameworks – Example checking component public class Accept extends OpenCOMComponent implements IUnknown, IAccept, IMetaInterface, ILifeCycle, IConnections { /** * Require use of both the meta architecture and meta interface MOPs */ public OCM_SingleReceptacle m_PSR_IMetaArchitecture; public OCM_SingleReceptacle m_PSR_IMetaInterface; // IAccept Interface implementation -- Programmatic check /** * This method performs validation checks on CF graphs. * @param graph A Vector containing the internal graph of the composite * @param Intfs A Vector describing the list of interfaces exposed * @param cComps An integer representing the number of components in the graph * @param cIntfs An integer describing the number of exposed interfaces * @return A boolean indicating a valid or invalid configuration **/ public boolean isValid(Vector graph, Vector Intfs, int cComps, int cIntfs) { /* * Hand coded check on the validity of the calculator framework. * In this case we want 2 components - with the calculator's receptacle * connected. */

79 The IDebug interface // Get the debug interface IDebug pIDebug = (IDebug) runtime.QueryInterface("OpenCOM.IDebug"); //dump component configuration to console pIDebug.dump(); // graphical repesentation of component configuration pIDebug.visualise();

80 Uses of OpenCOM (1) OpenORB : middleware – Configurable: adapt to needs of different application domains – Dynamically reconfigurable: to meet the needs of the changing environment Built on OpenCOM (the C implementation) – a given middleware instance is constructed as a set of OpenCOM component frameworks (=composed OpenCOM components) – Inside each component framework, a configuration manager applies application domain speciffic policies

81 Example of OpenCOM: OpenORB G.Blair et al, The Design and Implementation of Open ORB 2, in IEEE DS, 2001 G.Blair et al, Reflection, Self-Awareness and Self-Healing in OpenORB, in ACM WOSS, 2002

82 Uses of OpenCOM (2) Netkit: Programmable Networking Environments on Network Processors G. Coulson et al, A GENERIC COMPONENT MODEL FOR BUILDING SYSTEMS SOFTWARE, in ACM Trans. Comput. Syst. 26, 1 (Feb. 2008)

83 Summary Why use OpenCOM (or another similar component technology) ? –

84 Dynamic reconfiguration Dynamic reconfiguration refers to the ability to change the functionality of an application at runtime. It is needed in: – non-stop systems (e.g. business-critical systems) so that an application can be upgraded while it is running. – adaptive systems which change their behaviour in response to changes in their environment reconfiguration in general is a series of ‘add’, ‘replace’, ‘remove’ and ‘connect’ steps. OpenCOM components are deployed in a runtime environment which provides API functionality for creating,deleting, connecting, and disconnecting components. Therefore the basis of dynamic reconfiguration is already provided in OpenCOM components - but without any inherent support for safe reconfiguration! OpenCOM component frameworks add some safety mechanisms for the dynamic reconfiguration of their internal structure - init_arch_transaction()

85 Issues in Dynamic reconfiguration System protection: Assume that we want to replace a component. Disconnecting the component at an arbitrary time may cause problems to the application and the platform: – What if the component we just removed was about to call another component? – What if another component is about to call the component we just removed? – If the system does not cater for situations like the above, we might cause the entire application to crash. State transfer: The state of a component is a set of data. If the component does not rely on any data, we can characterize it as stateless. – By simply removing the old component and inserting the new one, we will possibly loose any state the old component had. This in turn might cause the entire application to loose its state. In OpenCOM, system protection is implemented only for the reconfiguration of component frameworks ! OpenCOM component framework transactions handle only the issue of System protection, NOT (application-specific) state transfer !

86 OpenCOM implementation detail The CF locking mechanism each component framework provides a readers/writers lock to access the local CF graph: – Each service call through any of the interfaces other than ICFMetaInterface accesses the lock as a reader (there can be n readers using the lock at any time). – Any call to change the configuration of the CF (through ICFMetaInterface), accesses the lock as a writer (a single writer can access the lock when there are no readers). The locks are in CFMetaInterface Locks are accessed in a pre-interceptor attached to all interfaces of a CF Locks are released in a post-interceptor attached to all interfaces of a CF

87 OpenCOM implementation detail Interceptors implement the CF locking mechanism public class CFInterceptors { /** * The reference to the interface of this object's corresponding component * framework. Used to invoke the access lock methods. **/ private ICFMetaInterface pMeta ; /** * Creates a new instance of CFInterceptors and sets the reference to the * CF's API. */ public CFInterceptors(ICFMetaInterface ThisComponentFramework) { pMeta = (ICFMetaInterface) ThisComponentFramework; } public synchronized int Pre0(String method, Object[] args){ … } public synchronized Object Post0(String method, Object result, Object[] args, Exception e){ … } }

88 OpenCOM implementation detail Interceptors implement the CF locking mechanism /** * Pre0 is inserted onto every exposed interface of the component * framework automatically. * Every operation invoked on the interface * forces the readers count to be incremented. If we are the first reader * we also get the write lock to prevent write access */ public synchronized int Pre0(String method, Object[] args){ // access 1 means we want the readers count sempahore pMeta.access_CF_graph_lock(1); // Got it, now update the readers counter int rc = pMeta.update_readers_count(1); // We are the first reader so we must acquire the CF lock sempahore if (rc==1){ // access 0 means we want the CF lock semaphore pMeta.access_CF_graph_lock(0); } // We've finished with the readers count, release the readers semaphore pMeta.release_CF_graph_lock(1); return 0; }

89 OpenCOM implementation detail Interceptors implement the CF locking mechanism /** * Post0 is inserted onto every exposed interface of the component * framework automatically. * It is executed after every operation of the intercepted interface. * It first decrements the readers count as we've finished read access. * The write lock is released if we are the last reader. */ public synchronized Object Post0(String method, Object result, Object[] args, Exception e){ // access 1 means we want the readers count sempahore pMeta.access_CF_graph_lock(1); // Got it, now update the readers counter int rc = pMeta.update_readers_count(-1); // We are the last reader so we must release the CF lock sempahore if (rc==0){ pMeta.release_CF_graph_lock(0); } // We've finished with the readers count, release the readers semaphore pMeta.release_CF_graph_lock(1); return result; }


Download ppt "CBSE Concepts – Short review “A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only."

Similar presentations


Ads by Google