OSGi Service Platform Release 4

Size: px
Start display at page:

Download "OSGi Service Platform Release 4"

Transcription

1 OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Revision November OSGi Alliance.

2 OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Copyright OSGi Alliance DISTRIBUTION AND FEEDBACK LICENSE, Version 2.0 DATE OF DISTRIBUTION: 24 November 2010 The OSGi Alliance hereby grants you a limited copyright license to copy and display this document (the Distribution ) in any medium without fee or royalty. This Distribution license is exclusively for the purpose of reviewing and providing feedback to the OSGi Alliance. You agree not to modify the Distribution in any way and further agree to not participate in any way in the making of derivative works thereof, other than as a necessary result of reviewing and providing feedback to the Distribution. You also agree to cause this notice, along with the accompanying consent, to be included on all copies (or portions thereof) of the Distribution. The OSGi Alliance also grants you a perpetual, non-exclusive, worldwide, fully paid-up, royalty free, limited license (without the right to sublicense) under any applicable copyrights, to create and/or distribute an implementation of the Distribution that: (i) fully implements the Distribution including all its required interfaces and functionality; (ii) does not modify, subset, superset or otherwise extend the OSGi Name Space, or include any public or protected packages, classes, Java interfaces, fields or methods within the OSGi Name Space other than those required and authorized by the Distribution. An implementation that does not satisfy limitations (i)-(ii) is not considered an implementation of the Distribution, does not receive the benefits of this license, and must not be described as an implementation of the Distribution. "OSGi Name Space" shall mean the public class or interface declarations whose names begin with "org.osgi" or any recognized successors or replacements thereof. The OSGi Alliance expressly reserves all rights not granted pursuant to these limited copyright licenses including termination of the license at will at any time. EXCEPT FOR THE LIMITED COPYRIGHT LICENSES GRANTED ABOVE, THE OSGi ALLIANCE DOES NOT GRANT, EITHER EXPRESSLY OR IMPLIEDLY, A LICENSE TO ANY INTELLECTUAL PROPERTY IT, OR ANY THIRD PARTIES, OWN OR CONTROL. Title to the copyright in the Distribution will at all times remain with the OSGi Alliance. The example companies, organizations, products, domain names, addresses, logos, people, places, and events depicted therein are fictitious. No association with any real company, organization, product, domain name, address, logo, person, place, or event is intended or should be inferred. THE DISTRIBUTION IS PROVIDED "AS IS," AND THE OSGi ALLIANCE (INCLUDING ANY THIRD PARTIES THAT HAVE CONTRIBUTED TO THE DISTRIBUTION) MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DISTRIBUTION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. NEITHER THE OSGi ALLIANCE NOR ANY THIRD PARTY WILL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY USE OR DISTRIBUTION OF THE DISTRIBUTION. Implementation of certain elements of this Distribution may be subject to third party intellectual property rights, including without limitation, patent rights (such a third party may or may not be a member of the OSGi Alliance). The OSGi Alliance is not responsible and shall not be held responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights. The Distribution is a draft. As a result, the final product may change substantially by the time of final publication, and you are cautioned against relying on the content of this Distribution. You are encouraged to update any implementation of the Distribution if and when such Distribution becomes a final specification. The OSGi Alliance is willing to receive input, suggestions and other feedback ( Feedback ) on the Distribution. By providing such Feedback to the OSGi Alliance, you grant to the OSGi Alliance and all its Members a non-exclusive, non-transferable, worldwide, perpetual, irrevocable, royalty-free copyright license to copy, publish, license, modify, sublicense or otherwise distribute and exploit your Feedback for any purpose. Likewise, if incorporation of your Feedback would cause an implementation of the Distribution, including as it may be modified, amended, or published at any point in the future ( Future Specification ), to necessarily infringe a patent or patent application that you own or control, you hereby commit to grant to all implementers of such Distribution or Future Specification an irrevocable, worldwide, sublicenseable, royalty free license 24 November 2010 Copyright OSGi Alliance 2010 Page ii.

3 OSGi Service Platform Release 4 Version 4.3 Early Draft 3 under such patent or patent application to make, have made, use, sell, offer for sale, import and export products or services that implement such Distribution or Future Specification. You warrant that (a) to the best of your knowledge you have the right to provide this Feedback, and if you are providing Feedback on behalf of a company, you have the rights to provide Feedback on behalf of your company; (b) the Feedback is not confidential to you and does not violate the copyright or trade secret interests of another; and (c) to the best of your knowledge, use of the Feedback would not cause an implementation of the Distribution or a Future Specification to necessarily infringe any third-party patent or patent application known to you. You also acknowledge that the OSGi Alliance is not required to incorporate your Feedback into any version of the Distribution or a Future Specification. I HEREBY ACKNOWLEDGE AND AGREE TO THE TERMS AND CONDITIONS DELINEATED ABOVE. 24 November 2010 Copyright OSGi Alliance 2010 Page iii.

4 OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Preface This document is Early Draft 3 of the OSGi Service Platform Release 4 Version 4.3 specifications. As an early draft, it contains non-final specification work and it is not organized in the format normally associated with final release OSGi specifications. This document contains copies of OSGi design documents which either propose to modify existing published OSGi specifications from the OSGi Service Platform Release 4 Version 4.2 specification documents or propose new specifications to potentially be incorporated in the final OSGi Service Platform Release 4 Specification Version 4.3 documents. Since this early draft is not a complete specification document, the reader is expected to be familiar with OSGi Technology and the currently published OSGi Service Platform Release 4 Version 4.2 specification documents. The reader should refer to for more information on the OSGi Technology. There the reader can find a description of the OSGi Technology, as well as links to whitepapers and the OSGi Service Platform Release 4 Version 4.2 specification documents, which are all available for download. Pursuant to the Distribution and Feedback License above, the OSGi expert groups welcome your feedback on this early draft. Feedback can be provided by opening a bug at product=osgi%20specification. BJ Hargrave Chief Technical Officer OSGi Alliance 24 November 2010 Copyright OSGi Alliance 2010 Page iv.

5 Core Design Documents OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Revision November OSGi Alliance.

6 Framework Hooks Final 41 Pages Abstract This RFC describes the means for a bundle to hook into the resolver, bundle events and accessing bundles with a bundle context. Copyright IBM Corporation 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

7 Framework Hooks Page 2 of 41 Final November 8, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Problem Description Requirements Technical Solution Terminology Synopsis Bundle Event Hook Bundle Find Hook Resolver Hook Resolution Process Begins Resolution Process Ends Hide Capabilities Effect of Singleton Bundles Limit the Set of Resolvable Bundles The Resolve Process Ordinary Services Exception handling Bundle Symbolic Name and Version Java Doc Command Line API JMX API Considered Alternatives Security Considerations Copyright IBM Corporation 2010

8 Framework Hooks Page 3 of 41 Final November 8, Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial 08/02/10 At the F2F in Ottawa it was decided to remove the concept of composite from the core framework. This RFC now is used to specify a set of core framework hooks that can be used to build isolation models on top of the framework. Thomas Watson, IBM [email protected] 08/18/10 Bundle EventHook takes a collection of bundle context now Bundle EventHook must be called once and only once per BundleEvent The Bundle FindHook only affects the behavior of BundleContext.getBundles() not BundleContext.getBundle(long) Describe dynamic resolution process. Add begin/end to ResolverHook Provide details on the resolve process and the interaction with the resolver hooks Specify a failure when a resolver hook attempts to start a nested resolve process. Imported javadoc. 09/21/10 Split ResolverHook into a factory and hook. Removed the restriction on the framework to have a single resovler process at a time. Copyright IBM Corporation 2010

9 Framework Hooks Page 4 of 41 Final November 8, 2010 Revision Date Comments 09/22/10 Minor updates to javadoc and use of triggered. Added sections about exception handling Add section that details how the framework obtains hook services (same as service hooks). 10/07/10 resolvebundles triggers only contains revisions for bundles in the INSTALLED state 10/08/10 Final version of RFC 11/08/10 Mark as Final to commence voting. BJ Hargrave 1 Introduction This RFC details how a bundle can hook into the various operations with in the module and lifecycle layers of the core Framework to influence the resolve operations and influence access to bundles through bundle events and the bundle context. 2 Application Domain This design is targeted at bundles which need to observe and manipulate select resolution operations and access to bundles through bundle events and the bundle context. In general these will be highly specialized bundles written by systems programmers. The design is not intended to be used by so-called normal application bundles. Copyright IBM Corporation 2010

10 Framework Hooks Page 5 of 41 Final November 8, Problem Description One of the key features of the module layer is to perform the resolution process which wires requirements (Import-Package, Require-Bundle etc.) to capabilities (Export-Package, Bundle-SymbolicName/Bundle-Version etc.). The module layer provides no means for a bundle (external to the framework) to observe or manipulate the resolution process as it occurs. Certain specialized bundles need to be able to alter the output results of the resolution process. Such purposes may include things like bundle grouping or scoping for isolation, etc. The lifecycle layer provides no means for a bundle (external to the framework) to observe or manipulate access to bundles. Certain specialized bundles need to be able to alter the output results of the lifecycle layer with respect to accessing bundle objects with the bundle event delivery operations and accessing bundle objects with the bundle context. Such purposes may include things like bundle grouping or scoping for isolation, etc. 4 Requirements RFP 100 contains a number of requirements used for this RFC. Additional requirements have been added or reworded to address some of the issues that have been observed since the original RFP. The solution MUST work with the current lifecycle layer. The solution MUST work with the current module layer. The solution MUST allow certain bundles to reduce the list of candidates (exported packages) available to resolve import package constraint from a given bundle. The solution MUST allow certain bundles to reduce the list of candidates (bundles) available to resolve require bundle constraints from a given bundle. The solution MUST allow certain bundles to reduce the list of candidates (host bundles) available to resolve fragment host constraints from a given fragment. The solution MUST allow certain bundles to reduce the list of generic capability (RFC 154) candidates available to resolve generic requirements from a given bundle. The solution MUST allow multiple bundles with identical symbolic-name and version to be installed without error. The solution MUST allow certain bundles to reduce the list of singleton bundles which influence the resolvability of a given singleton bundle. Copyright IBM Corporation 2010

11 Framework Hooks Page 6 of 41 Final November 8, 2010 The solution MUST allow certain bundles to reduce the list of bundles a bundle event is delivered to. The solution MUST allow certain bundles to reduce the list of bundles returned by a find bundle operation (BundleContext.getBundles()). The solution MUST be secured when java permissions are in effect. Security MUST not be used to provide the means to the solution. The solution MUST work without a security manager. 5 Technical Solution The OSGi framework has built-in support for bundle resolution primitives and bundle lifecycle primitives. The resolution primitives are quite complex as well as powerful. The resolver built into the framework provides the basis for which the complete module layer is built upon. However, the resolver operates on information that is not completely visible to the bundles and in most cases bundles cannot effect the results of the resolver. For example, it is not possible for a bundle outside of the framework reduce the set of exported packages available to resolve a particular import package from a certain bundle. Additionally, it is also not possible to allow bundles to influence the access to other bundle objects from a certain bundle. For example, when a find bundle operation is performed using a bundle context (getbundles() method) it is not possible to reduce the collection of bundles returned. Also, it is not possible to hide bundle events from certain bundles. Therefore, this framework hook specification provides a number of new mechanisms that closely interact with the built-in resolver and lifecycle layer of the framework. These interactions are not intended for use by application bundles. Modifying the behavior of the module and lifecycle layer requires developers to closely follow the semantics of the OSGi module and lifecycle model and this is often hard, requiring a significant amount of code. 5.1 Terminology Client The bundle that finds bundles or receives events about bundles. Also, the bundle which declares requirements which need to be resolved. Handler The bundle that registers a hook service uses this to: view or modify the resolution process view or modify find bundle operations view or modify bundle event delivery Capability Some feature that is declared with meta-data. For example, Export-Package. Copyright IBM Corporation 2010

12 Provider A bundle that provides a capability Consumer A client bundle that requires a capability Framework Hooks Page 7 of 41 Final November 8, 2010 Resolver The internal framework machinery that wires (resolves) constraints declared by a consumer to capabilities declared by a provider. Bundle Event Hook A bundle event hook intercepts bundle events before they are delivered to the client. The hook can select to remove events for specific bundles, which effectively allows the hook to hide bundle events from a bundle. Bundle Find Hook A bundle find hook intercepts the getbundle(s) call just before it returns the results to the client. The results can be influenced by removing bundle entries. The bundle find hook can be used to hide specific bundles for specific bundles. Resolver Hook A resolver hook intercepts the resolve process in the following ways: Remove specific capabilities available to resolve a specific client bundle Remove specific singleton bundles from influencing the resolvability of another specific singleton bundle. Remove specific bundles from a list of resolvable bundles to prevent specific bundles from resolving during a single resolution process. 5.2 Synopsis A bundle that needs to hide specific capabilities available to wire to from other bundles can register a resolver hook by registering a Resolver Hook service with the framework. If a resolve operation is performed it will pass this resolve hook information about the resolve process as it is occurring. The resolver hook can then inspect the arguments and optionally remove candidates available to a consumer to influence the resolver solution. A bundle that needs to hide bundle objects from other bundles can register a bundle find or event hook by registering a Bundle Find Hook service or a Bundle Event Hook service with the framework. If a bundle event is generated, it will pass this event to the bundle event hook. The event hook method can then inspect the arguments and optionally remove bundles from the event delivery list. When a bundle uses the Bundle Context getbundle(long) or getbundles method, the Bundle Find Hook is notified with a list of discovered bundles. The hook can then remove any bundles it wants to hide from the target bundle. 5.3 Bundle Event Hook To intercept events being delivered to bundles, a handler must register a bundle EventHook object as a service with the framework. The framework must then send all bundle events to all registered hooks. The calling order of the hooks is defined by the reversed compareto ordering of their Service Reference objects. That is, the service with the highest ranking number is called first. Bundle Event hooks are called after the event is generated but before they are delivered to any of the registered bundle listeners. Before the return, the handler can remove bundles from the given list. This allows a bundle event hook to hide bundle events for specific bundles. An event hook receives all events, INSTALLED, RESOLVED, STARTING, STARTED, STOPPING, STOPPED, UNRESOLVED, UPDATED, and UNINSTALLED, if and only if there one or more bundle listeners registered with the framework. Copyright IBM Corporation 2010

13 The bundle EventHook class has a single method: Framework Hooks Page 8 of 41 Final November 8, 2010 event(bundleevent, Collection<BundleContext>) A bundle event has been generated. The implementer of this method can optionally shrink the given collection of target bundles. One of the parameters of the event method is a collection of target bundle contexts. The handler can shrink this list by removing bundle contexts. The collection and its iterator must therefore implement the remove method. Removing a bundle context from the list of target bundle contexts will effectively hide the bundle event from the target bundle context and therefore any bundle listeners registered with that bundle context. The target bundle context can still get the bundle for the event with the BundleContext.getBundle(s) methods, though the Bundle Find Hook can be used to block this access to the bundle. The event method must be called one and only one time for each bundle event generated, this included bundle events which are generated when there are no bundle listeners registered. The event method must be called on the same thread that is performing the action which generated the specified event. The specified collection includes bundle contexts with synchronous and asynchronous bundle listeners registered with them. Implementations of the Bundle Event Hook must ensure that target bundles continue to see a consistent set of bundle events. Bundle events can be used in a stat machine. Such state machines can get confused if some events are missed. For example, if a Bundle Tracker sees a STARTED event but is hidden from the corresponding STOPPED event then the tracker will still think the bundle is active. A simple solution is to stop the target bundle when the filter is put in place. However, when the bundle that implements the bundle event hook is stopped, it will of course no longer be able to filter events and the target bundle might see bundle events for bundles it was not aware of. As a best practice a bundle event hook should not hide an event from the bundle which the event is for. 5.4 Bundle Find Hook The Bundle Find Hook is called when a target bundle searches the framework with the getbundles() methods on BundleContext. A registered Bundle Find Hook service gets a chance to inspect the returned set of bundles and can optionally shrink the set of returned bundles. The order in which the bundle find hooks are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first. The bundle FindHook class has a single method: find(bundlecontext, Collection<Bundle>) - The callback when a bundle calls the getbundle(long) or getbundles() methods on BundleContext. As parameters, it gets the bundle context of the calling bundle, and a set of bundles that will be returned. This list can be shortened by removing bundles from the given list. The purpose of the Bundle Find Hook, is to limit the visibility of bundles to selected target bundles. For this reason the hook implementation can remove selected bundles from the result collection. The collection and its iterator must therefor implement the remove method. As a best practice a bundle find hook should not hide a bundle from itself. 5.5 Resolver Hook A Resolver Hook Factory creates a resolver hook which is used by the framework for a single resolve process. The Resolver Hook is called during a resolution process. A Resolver Hook gets a chance to influence the outcome of a resolution process in the following ways. Copyright IBM Corporation 2010

14 Limit the visibility of a capability to selected target bundles. Framework Hooks Page 9 of 41 Final November 8, 2010 Limit the effect a singleton bundle has on the resolvability of selected target bundles. Limit the set of bundles that will be available for resolution to a set of selected target bundles. There are types of resolve processes that can be initiated. 1. A static bundle resolution operation. This resolve process is necessary any time one or more bundles transitions from the INSTALLED state to the RESOLVED state. During this resolve process the framework attempts to resolve static requirements specified by the bundles 2. A dynamic import resolution operation. This resolve process is necessary any time a request is made to wire a dynamic import for a bundle. A resolver hook may influence the outcome of a resolve process by removing entries from shrinkable collections that are passed to the hook during a resolve process. A shrinkable collection is a collection that supports all remove operations. Any other attempts to modify a shrinkable collection will result in an UnsupportedOperationException being thrown Resolution Process Begins When a resolve process begins the framework must ask each Resolver Hook Factory to provide a Resolver Hook which will be used for the duration of the resolve process. This is done by calling the begin method on a Resolver Hook Factory. A resolver hook Factory is informed about a resolution process beginning with the following method: begin(collection<bundlerevision> triggeres) This method is called by the framework each time a resolve process begins to obtain a resolver hook instance. This resolver hook instance will be used for the duration of the resolve process. At the end of the resolve process the method ResolverHook.end() must be called by the framework and the framework must not hold any references of the resolver hook instance. The triggers represent the collection of bundles which triggered the resolve process. This collection may be empty if the triggers cannot be determined by the framework. In most cases the triggers can easily be determined. Calling certain methods on bundle when a bundle is in the INSTALLED state will cause the framework to begin a resolve process in order to resolve the bundle. The following methods will start a resolve process in this case: start loadclass findentries getresource getresources In such cases the collection will contain the single bundle which the framework is trying to resolve. Other cases will cause multiple bundles to be included in the trigger bundles collection. When resolvebundles is called the Copyright IBM Corporation 2010

15 Framework Hooks Page 10 of 41 Final November 8, 2010 collection of triggers must include all the current bundle revisions for bundles passed to resolvebundles which are in the INSTALLED state. When FrameworkWiring.refreshBundles(Collection, org.osgi.framework.frameworklistener...) is called the collection of triggers is determined with the following steps: If the collection of bundles passed is null then FrameworkWiring.getRemovalPendingBundles() is called to get the initial collection of bundles. The equivalent of calling FrameworkWiring.getDependencyClosure(Collection) is called with the initial collection of bundles to get the dependency closure collection of the bundles being refreshed. Remove any non-active bundles from the dependency closure collection. For each bundle remaining in the dependency closure collection get the current bundle revision and add it to the collection of triggers. The order in which the resolver hook factory begin methods are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first Resolution Process Ends A resolver hook is informed about a resolution process ending with the following method: end() - This method is called once at the end of the resolve process. After the end method is called the resolve process has ended. The framework must not hold onto this resolver hook instance after end has been called. The order in which the resolver hook end methods are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first Hide Capabilities A Resolver Hook can hide capabilities using the following method: filtermatches(bundlerevision requirer, Collection<Capability> candidates) A bundle (requirer) has a constraint which can be satisfied (matched) with the supplied collection of candidates (capabilities). The implementor of this method can optionally shrink the list of candidate capabilities. One of the parameters of the filtermatches method is a list of capabilities. The handler can shrink this collection by removing capabilities. The collection and its iterator must therefore implement the remove method. Removing a capability from the list of candidates will effectively hide the capability from the target bundle. This will prevent the target bundle from getting wired to the capability. The order in which the resolver hook filtermatches methods are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first Effect of Singleton Bundles A Resolver Hook can change the effect of singleton bundles using the following method: filtersingletoncollisions(capability singleton, Collection<Capability> collisioncandidates) An osgi.bundle singleton capability has the same symbolic-name as the given collection of osgi.bundle capability Copyright IBM Corporation 2010

16 Framework Hooks Page 11 of 41 Final November 8, 2010 candidates. The implementor of this method can optionally shrink the list of collision candidate capabilities. One of the parameters of the filtersingletoncollisions method is a set of capabilities. The handler can shrink this collection by removing capabilities. The collection and its iterator must therefore implement the remove method. Removing a capability from the list of collision candidates will effectively hide the collision candidate from the target singleton bundle. This will allow the target singleton bundle to resolve regardless of the resolution state of the collision candidate. The framework may call this method multiple times for the same singleton capability. For example, as a first pass a framework may want to determine if a singleton bundle is resolvable first based on the presence of other already resolved singleton capabilities. Later the framework may call this method again to determine which singleton capabilities from unresolved bundles to allow to resolve. The order in which the resolver hook filtersingletoncollisions methods are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first Limit the Set of Resolvable Bundles A Resolver hook can limit the set of bundles that will be allowed to resolve for a single resolve operation with the following method: filterresolvable(collection<bundlerevision> candidates) A resolve operation has been started. The given collection of candidate bundles are available to resolve (i.e. they are currently unresolved). The implementor of this method can optionally shrink the collection of candidate bundles. The candidates parameters of the filterresolvable method is a collection of bundle revisions. The handler can shrink this collection by removing candidate bundle revisions. The collection and its iterator must therefore implement the remove method. Removing a candidate bundle from the collection of candidates will effectively prevent the bundle from resolving for the current resolve operation. The order in which the resolver hook filterresolvable methods are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first. For a dynamic import resolution process it is acceptable for the framework to pass an empty collection of resolvable candidates. This indicates that the framework will not cause any bundles to transition from INSTALLED to RESOLVED during a dynamic import package resolution The Resolve Process The following steps outline the way a framework uses the resolver hooks during a resolve process. 1. Collect a snapshot of registered resolver hook factories that will be called during the current resolve process. Any hook factories registered after the snapshot is taken must not be called during the current resolve process. A resolver hook factory contained in the snapshot may become unregistered during the resolve process. The framework should handle this and stop calling the resolver hook instance provided by the unregistered hook factory for the remainder of the resolve process. Each registered resolver hook factory service in the snapshot will be obtained by the framework (by calling BundleContext.getService method using the system bundle context). 2. For each registered hook factory, call the begin() method to inform the hooks about a resolve process beginning and to obtain a Resolver Hook instance that will be used for the duration of the resolve process. Copyright IBM Corporation 2010

17 Framework Hooks Page 12 of 41 Final November 8, Determine the collection of unresolved bundle revisions that may be considered for resolution during the current resolution process and place each of the bundle revisions in a shrinkable collection R. a) For each resolver hook, call the filterresolveable method with the shrinkable collection R. 4. The shrinkable collection R now contains all the unresolved bundle revisions that may end up as resolved at the end of the current resolve process. Any other bundle revisions that got removed from the shrinkable collection R must not end up as resolved at the end of the current resolve process. 5. For each bundle revision B left in the shrinkable collection R that represents a singleton bundle, do the following: a) Determine the collection of available capabilities that have a name space of osgi.bundle, are singletons, and have the same symbolic name as the singleton bundle revision B and place each of the matching capabilities into a shrinkable collection S. b) Remove the osgi.bundle capability provided by the bundle revision B from the shrinkable collection S. A singleton bundle cannot collide with itself. c) For each resolver hook call the filtersingletoncollisions method with the osgi.bundle capability provided by bundle revision B and the shrinkable collection S. d) The shrinkable collection S now contains all the singleton osgi.bundle capabilities that can influence the ability of bundle revision B to resolve. 6. During a resolve process a framework is free to attempt to resolve any or all bundles contained in the shrinkable collection R. For each bundle revision B left in the shrinkable collection R which the framework attempts to resolve the following steps must be followed: a) For each requirement T specified by bundle revision B, determine the collection of capabilities that satisfy (or match) the requirement and place each matching capability into a shrinkable collection C. A capability is considered to match a particular requirement if its attributes satisfy a specified requirement and the requirer bundle has permission to access the capability. b) For each resolver hook, call the filtermatches method with the bundle revision B and the shrinkable collection C. c) The shrinkable collection C now contains all the capabilities that may be used to satisfy the requirement T. Any other capabilities that got removed from the shrinkable collection C must not be used to satisfy requirement T. 7. For each resolver hook, call the end method to inform the hook about a resolve process ending. 8. For each hook factory obtained by the framework in the first step; unget the service instance (by calling BundleContext.ungetService using the system bundle context). In cases where the a shrinkable collection becomes empty the framework is required to call the remaining hooks. The above steps are meant to illustrate how the resolve hooks are used by the framework. They are not normative. The nature of the resolve process and the resolve algorithm can require some back tracking by the framework implementation. Because of this it is acceptable for the framework to call methods on the ResolverHook multiple times with similar or identical parameters during a single resolve process. This is true for all methods except the begin and end methods. The begin and end methods must be called once and only once for each resolve process. Copyright IBM Corporation 2010

18 Framework Hooks Page 13 of 41 Final November 8, 2010 Resolver hooks are low level. Implementations of the resolver hook must be careful not to create an unresolvable state which is very hard for a developer or a provisioner to diagnose. Resolver hooks also must not be allowed to start another resolve process (e.g. by calling Bundle.start() or FrameworkWiring.resolveBundles). The framework must detect this and throw an IllegalStateException from the resolve process. In cases where a BundleException can be thrown (e.g. Bundle.start()) the IllegalStateException must be the cause of the BundleException and the BundleException must be of type BundleException.RESOLVE_ERROR. In cases where an exception cannot be propagated to a caller (e.g. dynamic import resolution) a FrameworkEvent of type ERROR must be published. 5.6 Ordinary Services All hooks are treated as ordinary services. If the framework uses them, their Service References will show that the system bundle is using them, and if a hook is a Service Factory, then the actual instance will be properly created. The only speciality of the service hooks (defined in chapter 12 of R4.2 specification) is that the framework must not use them for the other hooks themselves. That is, the service Event and service Find Hooks can not be used to hide the other hook services from the framework. 5.7 Exception handling If a hook implementation method throws an exception the framework must publish a FrameworkEvent of type error and continue to call the remaining hooks for the method being called. The framework may stop calling the hook which threw the exception for future operations but the framework is not obligated to. 5.8 Bundle Symbolic Name and Version In R4.0 the concept of a bundle symbolic name and version were formalized. The unique content of a bundle can be identified by its unique bundle symbolic name and version. The R4.0 specification also caused an installation exception if the same bundle (with identical bundle symbolic name and version) was installed multiple times. This restriction is being lifted in this release to allow the same bundle to be installed multiple times (using unique location strings). A new framework configuration option (org.osgi.framework.bsnversion) has been added to enable this feature. The values of this property can be multiple or single. The value multiple specifies the framework will allow multiple bundles to be installed having the same symbolic name and version. The value single specifies the framework will only allow a single bundle to be installed for a given symbolic name and version. It will be an error to install a bundle or update a bundle to have the same symbolic name and version as another installed bundle. The default value is single. Note that this default may change in a future specification. 6 Java Doc OSGi Javadoc 10/8/10 11:17 AM Package Summary Page Copyright IBM Corporation 2010

19 Framework Hooks Page 14 of 41 Final November 8, 2010 org.osgi.frame work.hooks.bu ndle org.osgi.frame work.hooks.res olver org.osgi.frame work.wiring Framework Bundle Hooks Package Version Framework Resolver Hooks Package Version Framework Wiring Package Version Copyright IBM Corporation 2010

20 Package org.osgi.framework.hooks.bundle Package org.osgi.framework.hooks.bundle Framework Bundle Hooks Package Version 1.0. See: Description Interface Summary EventHook OSGi Framework Bundle Event Hook Service. 16 FindHook OSGi Framework Bundle Context Hook Service. 17 Package org.osgi.framework.hooks.bundle Description Framework Bundle Hooks Package Version 1.0. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. Example import for consumers using the API in this package: Import-Package: org.osgi.framework.hooks.bundle; version="[1.0,2.0)" Page OSGi Javadoc -- 8/18/10 Page 15 of 41

21 Package org.osgi.framework.hooks.bundle Interface EventHook org.osgi.framework.hooks.bundle public interface EventHook OSGi Framework Bundle Event Hook Service. Bundles registering this service will be called during framework lifecycle (install, start, stop, update, and uninstall bundle) operations. Version: $Id: 18ea1ec1f14f47410a43e99be4da3b $ ThreadSafe Method Summary void event(org.osgi.framework.bundleevent event, Collection<org.osgi.framework.BundleContext> contexts) Bundle event hook method. Pag e 16 Method Detail event void event(org.osgi.framework.bundleevent event, Collection<org.osgi.framework.BundleContext> contexts) Bundle event hook method. This method is called prior to bundle event delivery when a bundle is installed, resolved, started, stopped, unresolved, or uninstalled. This method can filter the bundles which receive the event. This method must be called by the framework one and only one time for each bundle event generated, this included bundle events which are generated when there are no bundle listeners registered. This method must be called on the same thread that is performing the action which generated the specified event. The specified collection includes bundle contexts with synchronous and asynchronous bundle listeners registered with them. Parameters: event - The bundle event to be delivered contexts - A collection of Bundle Contexts for bundles which have listeners to which the specified event will be delivered. The implementation of this method may remove bundle contexts from the collection to prevent the event from being delivered to the associated bundles. The collection supports all the optional Collection operations except add and addall. Attempting to add to the collection will result in an UnsupportedOperationException. The collection is not synchronized. OSGi Javadoc -- 8/18/10 Page 16 of 41

22 Interface EventHook Interface FindHook org.osgi.framework.hooks.bundle public interface FindHook OSGi Framework Bundle Context Hook Service. Bundles registering this service will be called during framework bundle find (get bundles) operations. Version: $Id: 2f5bd0fa306e792eb88f254975e301b20d7f969d $ ThreadSafe Method Summary void find(org.osgi.framework.bundlecontext context, Collection<org.osgi.framework.Bundle> bundles) Find hook method. Pag e 17 Method Detail find void find(org.osgi.framework.bundlecontext context, Collection<org.osgi.framework.Bundle> bundles) Find hook method. This method is called during the bundle find operation (for example, getbundle and org.osgi.framework.bundlecontext.getbundles() methods). This method can filter the result of the find operation. Parameters: context - The bundle context of the bundle performing the find operation. bundles - A collection of Bundles to be returned as a result of the find operation. The implementation of this method may remove bundles from the collection to prevent the bundles from being returned to the bundle performing the find operation. The collection supports all the optional Collection operations except add and addall. Attempting to add to the collection will result in an UnsupportedOperationException. The collection is not synchronized. OSGi Javadoc -- 8/18/10 Page 17 of 41

23 Interface FindHook Package org.osgi.framework.hooks.resolver Framework Resolver Hooks Package Version 1.0. See: Description Interface Summary ResolverHook ResolverHookF actory OSGi Framework Resolver Hook instances are obtained from the OSGi Framework Resolver Hook Factory service. OSGi Framework Resolver Hook Factory Service. 22 Package org.osgi.framework.hooks.resolver Description Framework Resolver Hooks Package Version 1.0. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. Example import for consumers using the API in this package: Import-Package: org.osgi.framework.hooks.resolver; version="[1.0,2.0)" Page 19 OSGi Javadoc -- 8/18/10 Page 18 of 41

24 Package org.osgi.framework.hooks.resolver Interface ResolverHook org.osgi.framework.hooks.resolver public interface ResolverHook OSGi Framework Resolver Hook instances are obtained from the OSGi Framework Resolver Hook Factory service. A Resolver Hook instance is called by the framework during a resolve process. A resolver hook may influence the outcome of a resolve process by removing entries from shrinkable collections that are passed to the hook during a resolve process. A shrinkable collection is a Collection that supports all remove operations. Any other attempts to modify a shrinkable collection will result in an UnsupportedOperationException being thrown. The following steps outline the way a framework uses the resolver hooks during a resolve process. 1. Collect a snapshot of registered resolver hook factories that will be called during the current resolve process. Any hook factories registered after the snapshot is taken must not be called during the current resolve process. A resolver hook factory contained in the snapshot may become unregistered during the resolve process. The framework should handle this and stop calling the resolver hook instance provided by the unregistered hook factory for the remainder of the resolve process. 2. For each registered hook factory call the ResolverHookFactory.begin(Collection) method to inform the hooks about a resolve process beginning and to obtain a Resolver Hook instance that will be used for the duration of the resolve process. 3. Determine the collection of unresolved bundle revisions that may be considered for resolution during the current resolution process and place each of the bundle revisions in a shrinkable collection R. a. For each resolver hook call the filterresolvable(collection) method with the shrinkable collection R. 4. The shrinkable collection R now contains all the unresolved bundle revisions that may end up as resolved at the end of the current resolve process. Any other bundle revisions that got removed from the shrinkable collection R must not end up as resolved at the end of the current resolve process. 5. For each bundle revision B left in the shrinkable collection R that represents a singleton bundle do the following: a. Determine the collection of available capabilities that have a name space of osgi.bundle, are singletons, and have the same symbolic name as the singleton bundle revision B and place each of the matching capabilities into a shrinkable collection S. b. Remove the osgi.bundle capability provided by bundle revision B from shrinkable collection S. A singleton bundle cannot collide with itself. c. For each resovler hook call the filtersingletoncollisions(capability, Collection) with the osgi.bundle capability provided by bundle revision B and the shrinkable collection S d. The shrinkable collection S now contains all singleton osgi.bundle capabilities that can influence the ability of bundle revision B to resolve. 6. During a resolve process a framework is free to attempt to resolve any or all bundles contained in shrinkable collection R. For each bundle revision B left in the shrinkable collection R which the framework attempts to resolve the following steps must be followed: a. For each requirement T specified by bundle revision B determine the collection of capabilities that satisfy (or match) the requirement and place each matching capability into a shrinkable collection C. A capability is considered to match a particular requirement if its attributes satisfy a specified requirement and the requirer bundle has permission to access the capability. b. For each resolver hook call the filtermatches(bundlerevision, Collection) with the bundle revision B and the shrinkable collection C. c. The shrinkable collection C now contains all the capabilities that may be used to satisfy the requirement T. Any other capabilities that got removed from the shrinkable collection C must not be used to satisfy requirement T. 7. For each resolver hook call the end() method to inform the hooks about a resolve process ending. In all cases, the order in which the resolver hooks are called is the reverse compareto ordering of their Service References. That is, the service with the highest ranking number must be called first. In cases where a shrinkable collection becomes empty the framework is required to call the remaining registered hooks. Resolver hooks are low level. Implementations of the resolver hook must be careful not to create an unresolvable state which is very hard for a developer or a provisioner to diagnose. Resolver hooks also must not be allowed to start another synchronous resolve process (e.g. by calling org.osgi.framework.bundle.start() or OSGi Javadoc -- 8/18/10 Page 19 of 41

25 Package org.osgi.framework.hooks.resolver FrameworkWiring.resolveBundles(Collection)). The framework must detect this and throw an IllegalStateException. Version: $Id: 49bcead9ff37ad2c864c0b0f2ca510f0be04f835 $ See Also: ResolverHookFactory ThreadSafe Method Summary void void void void end() This method is called once at the end of the resolve process. filtermatches(bundlerevision requirer, Collection<Capability> candidates) Filter matches hook method. filterresolvable(collection<bundlerevision> candidates) Filter resolvable candidates hook method. filtersingletoncollisions(capability singleton, Collection<Capability> collisioncandidates) Filter singleton collisions hook method. Pag e Method Detail filterresolvable void filterresolvable(collection<bundlerevision> candidates) Filter resolvable candidates hook method. This method may be called multiple times during a single resolve process. This method can filter the collection of candidates by removing potential candidates. Removing a candidate will prevent the candidate from resolving during the current resolve process. Parameters: candidates - the collection of resolvable candidates available during a resolve process. filtersingletoncollisions void filtersingletoncollisions(capability singleton, Collection<Capability> collisioncandidates) Filter singleton collisions hook method. This method is called during the resolve process for the specified singleton. The specified singleton represents a singleton capability and the specified collection represent a collection of singleton capabilities which are considered collision candidates. The singleton capability and the collection of collision candidates must all use the same name space. Currently only capabilities with the name space of osgi.bundle can be singletons. In that case all the collision candidates have the name space of osgi.bundle, are singletons, and have the same symbolic name as the specified singleton capability. In the future, capabilities in other name spaces may support the singleton concept. Hook implementations should be prepared to receive calls to this method for capabilities in name spaces other than osgi.bundle. This method can filter the list of collision candidates by removing potential collisions. Removing a collision candidate will allow the specified singleton to resolve regardless of the resolution state of the removed collision candidate. Parameters: singleton - the singleton involved in a resolve process collisioncandidates - a collection of singleton collision candidates OSGi Javadoc -- 8/18/10 Page 20 of 41

26 Package org.osgi.framework.hooks.resolver filtermatches void filtermatches(bundlerevision requirer, Collection<Capability> candidates) Filter matches hook method. This method is called during the resolve process for the specified requirer. The collection of candidates match a requirement for the requirer. This method can filter the collection of matching candidates by removing candidates from the collection. Removing a candidate will prevent the resolve process from choosing the removed candidate to satisfy a requirement for the requirer. All of the candidates will have the same name space and will match a requirement of the requirer. If the Java Runtime Environment supports permissions then the collection of candidates will only contain candidates for which the requirer has permission to access. Parameters: requirer - the bundle revision which contains a requirement candidates - a collection of candidates that match a requirement of the requirer end void end() This method is called once at the end of the resolve process. After the end method is called the resolve process has ended. The framework must not hold onto this resolver hook instance after end has been called. OSGi Javadoc -- 8/18/10 Page 21 of 41

27 Interface ResolverHook Interface ResolverHookFactory org.osgi.framework.hooks.resolver public interface ResolverHookFactory OSGi Framework Resolver Hook Factory Service. Bundles registering this service will be called by the framework during a bundle resolver process to obtain a resolver hook instance which will be used for the duration of a resolve process. Version: $Id: 08a6fba0f95499d b88256d33e1ce4 $ See Also: ResolverHook ThreadSafe Method Summary ResolverHo ok begin(collection<bundlerevision> triggers) This method is called by the framework each time a resolve process begins to obtain a resolver hook instance. Pag e 22 Method Detail begin ResolverHook begin(collection<bundlerevision> triggers) This method is called by the framework each time a resolve process begins to obtain a resolver hook instance. This resolver hook instance will be used for the duration of the resolve process. At the end of the resolve process the method ResolverHook.end() must be called by the framework and the framework must not hold any references of the resolver hook instance. The triggers represent the collection of bundles which triggered the resolve process. This collection may be empty if the triggers cannot be determined by the framework. In most cases the triggers can easily be determined. Calling certain methods on bundle when a bundle is in the INSTALLED state will cause the framework to begin a resolve process in order to resolve the bundle. The following methods will start a resolve process in this case: start loadclass findentries getresource getresources In such cases the collection will contain the single bundle which the framework is trying to resolve. Other cases will cause multiple bundles to be included in the trigger bundles collection. When resolvebundles is called the collection of triggers must include all the current bundle revisions for bundles passed to resolvebundles which are in the INSTALLED state. When FrameworkWiring.refreshBundles(Collection, org.osgi.framework.frameworklistener...) is called the collection of triggers is determined with the following steps: If the collection of bundles passed is null then FrameworkWiring.getRemovalPendingBundles() is called to get the initial collection of bundles. The equivalent of calling FrameworkWiring.getDependencyClosure(Collection) is called with the initial collection of bundles to get the dependency closure collection of the bundles being refreshed. OSGi Javadoc -- 8/18/10 Page 22 of 41

28 Interface ResolverHook Remove any non-active bundles from the dependency closure collection. For each bundle remaining in the dependency closure collection get the current bundle revision and add it to the collection of triggers. Parameters: triggers - an unmodifiable collection of bundles which triggered the resolve process. This collection may be empty if the collection of trigger bundles cannot be determined. Returns: a resolver hook instance to be used for the duration of the resolve process. A null value may be returned which indicates this resolver hook factory abstains from the resolve process. OSGi Javadoc -- 8/18/10 Page 23 of 41

29 Package org.osgi.framework.wiring Package org.osgi.framework.wiring Framework Wiring Package Version 1.0. See: Description Interface Summary BundleRevisio n Bundle Revision. 25 BundleWiring A wiring for a bundle. 27 BundleWirings The in use bundle wirings for a bundle. 32 Capability A capability that has been declared from a bundle revision. 33 FrameworkWiri ng WiredCapabilit y Query and modify wiring information for the framework. 36 A wired capability that has been provided from a bundle wiring. 39 Package org.osgi.framework.wiring Description Framework Wiring Package Version 1.0. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. For example: Import-Package: org.osgi.framework.wiring; version="[1.0,2.0)" Page OSGi Javadoc -- 8/18/10 Page 24 of 41

30 Interface BundleRevision Interface BundleRevision org.osgi.framework.wiring All Superinterfaces: org.osgi.framework.bundlereference public interface BundleRevision extends org.osgi.framework.bundlereference Bundle Revision. Since a bundle update can change the entries in a bundle, different bundle wirings for the same bundle can be associated with different bundle revisions. The current bundle revision for a bundle can be obtained by calling bundle.adapt(bundlerevision.class). Version: $Id: 1a e7071a1eb504afbc3f75f8af1aff01 $ ThreadSafe Field Summary int TYPE_FRAGMENT Bundle revision type indicating the bundle revision is a fragment. Method Summary List<Capab ility> String int org.osgi.f ramework.v ersion getdeclaredcapabilities(string namespace) Returns the capabilities declared by this bundle revision. getsymbolicname() Returns the symbolic name for this bundle revision. gettypes() Returns the special types of this bundle revision. getversion() Returns the version for this bundle revision. Pag e 25 Pag e Methods inherited from interface org.osgi.framework.bundlereference getbundle Field Detail TYPE_FRAGMENT public static final int TYPE_FRAGMENT = 1 Bundle revision type indicating the bundle revision is a fragment. See Also: gettypes() Method Detail getsymbolicname String getsymbolicname() OSGi Javadoc -- 8/18/10 Page 25 of 41

31 Interface BundleRevision Returns the symbolic name for this bundle revision. Returns: The symbolic name for this bundle revision. See Also: org.osgi.framework.bundle.getsymbolicname() getversion org.osgi.framework.version getversion() Returns the version for this bundle revision. Returns: The version for this bundle revision, or org.osgi.framework.version.emptyversion if this bundle revision has no version information. See Also: org.osgi.framework.bundle.getversion() getdeclaredcapabilities List<Capability> getdeclaredcapabilities(string namespace) Returns the capabilities declared by this bundle revision. Parameters: namespace - The name space of the declared capabilities to return or null to return the provided capabilities from all name spaces. Returns: A list containing a snapshot of the declared Capabilitys, or an empty list if this bundle revision declares no capabilities in the specified name space. The list contains the provided capabilities in the order they are specified in the manifest. gettypes int gettypes() Returns the special types of this bundle revision. The bundle revision type values are: TYPE_FRAGMENT A bundle revision may be more than one type at a time. A type code is used to identify the bundle revision type for future extendability. If this bundle revision is not one or more of the defined types then 0 is returned. Returns: The special types of this bundle revision. The type values are ORed together. OSGi Javadoc -- 8/18/10 Page 26 of 41

32 Interface BundleWiring Interface BundleWiring org.osgi.framework.wiring All Superinterfaces: org.osgi.framework.bundlereference public interface BundleWiring extends org.osgi.framework.bundlereference A wiring for a bundle. Each time a bundle is resolved, a new bundle wiring for the bundle is created. A bundle wiring consists of a bundle and it attached fragments and represents the dependencies with other bundle wirings. The bundle wiring for a bundle is the current bundle wiring if the bundle is resolved and the bundle wiring is the most recent bundle wiring. All bundles with non-current, in use bundle wirings are considered removal pending. A bundle wiring is in use if it is the current wiring or if some other in use bundle wiring is dependent upon it. For example, wired to a package exported by the bundle wiring or requires the bundle wiring. An in use bundle wiring has a class loader. Once a bundle wiring is no longer in use, it is considered stale and is discarded by the framework. A list of all in use bundle wirings for a bundle can be obtained by calling bundle.adapt(bundlewirings.class). getwirings(). For non-fragment bundles, the first item in the returned list is the current bundle wiring. The current bundle wiring for a non-fragment bundle can be obtained by calling bundle.adapt(bundlewiring.class). A fragment bundle does not itself have bundle wirings. So calling bundle.adapt(bundlewiring.class) on a fragment must return null. Version: $Id: 6787c55f83f520429d63e93024ccf9f22821c4c8 $ ThreadSafe Field Summary int int int FINDENTRIES_RECURSE The find entries operation must recurse into subdirectories. LISTRESOURCES_LOCAL The list resource names operation must limit the result to the names of matching resources contained in this bundle wiring's bundle revision and its attached fragment revisions. LISTRESOURCES_RECURSE The list resource names operation must recurse into subdirectories. Method Summary List<URL> BundleRevi sion ClassLoade r List<Bundl erevision> List<Wired Capability > List<Wired Capability > findentries(string path, String filepattern, int options) Returns entries in this bundle wiring's bundle revision and its attached fragment revisions. getbundlerevision() Returns the bundle revision for the bundle in this bundle wiring. getclassloader() Returns the class loader for this bundle wiring. getfragmentrevisions() Returns the bundle revisions for all attached fragments of this bundle wiring. getprovidedcapabilities(string capabilitynamespace) Returns the capabilities provided by this bundle wiring. getrequiredcapabilities(string capabilitynamespace) Returns the required capabilities used by this bundle wiring. Pag e Pag e OSGi Javadoc -- 8/18/10 Page 27 of 41

33 Interface BundleWiring boolean boolean List<Strin g> iscurrent() Returns true if this bundle wiring is the current bundle wiring. isinuse() Returns true if this bundle wiring is in use. listresources(string path, String filepattern, int options) Returns the names of resources visible to this bundle wiring's class loader Methods inherited from interface org.osgi.framework.bundlereference getbundle Field Detail FINDENTRIES_RECURSE public static final int FINDENTRIES_RECURSE = 1 The find entries operation must recurse into subdirectories. This bit may be set when calling findentries(string, String, int) to specify the result must include the matching entries from the specified path and its subdirectories. If this bit is not set, then the result must only include matching entries from the specified path. See Also: findentries(string, String, int) LISTRESOURCES_RECURSE public static final int LISTRESOURCES_RECURSE = 1 The list resource names operation must recurse into subdirectories. This bit may be set when calling listresources(string, String, int) to specify the result must include the names of matching resources from the specified path and its subdirectories. If this bit is not set, then the result must only include names of matching resources from the specified path. See Also: listresources(string, String, int) LISTRESOURCES_LOCAL public static final int LISTRESOURCES_LOCAL = 2 The list resource names operation must limit the result to the names of matching resources contained in this bundle wiring's bundle revision and its attached fragment revisions. This bit may be set when calling listresources(string, String, int) to specify the result must only include the names of matching resources contained in this bundle wiring's bundle revision and its attached fragment revisions. If this bit is not set, then the result must include the names of matching resources reachable from this bundle wiring's class loader which may include the names of matching resources contained in imported packages and required bundles. See Also: listresources(string, String, int) OSGi Javadoc -- 8/18/10 Page 28 of 41

34 Interface BundleWiring Method Detail iscurrent boolean iscurrent() Returns true if this bundle wiring is the current bundle wiring. The bundle wiring for a bundle is the current bundle wiring if the bundle is resolved and the bundle wiring is the most recent bundle wiring. All bundles with non-current, in use bundle wirings are considered removal pending. Returns: true if this bundle wiring is the current bundle wiring; false otherwise. isinuse boolean isinuse() Returns true if this bundle wiring is in use. A bundle wiring is in use if it is the current wiring or if some other in use bundle wiring is dependent upon it. Once a bundle wiring is no longer in use, it is considered stale and is discarded by the framework. Returns: true if this bundle wiring is in use; false otherwise. getprovidedcapabilities List<WiredCapability> getprovidedcapabilities(string capabilitynamespace) Returns the capabilities provided by this bundle wiring. Parameters: capabilitynamespace - The name space of the provided capabilities to return or null to return the provided capabilities from all name spaces. Returns: A list containing a snapshot of the WiredCapabilitys, or an empty list if this bundle wiring provides no capabilities in the specified name space. If this bundle wiring is not in use, null will be returned. The list contains the provided capabilities in the order they are specified in the manifest. getrequiredcapabilities List<WiredCapability> getrequiredcapabilities(string capabilitynamespace) Returns the required capabilities used by this bundle wiring. The result of this method can change if this bundle wiring requires additional capabilities. Parameters: capabilitynamespace - The name space of the required capabilities to return or null to return the required capabilities from all name spaces. Returns: A list containing a snapshot of the WiredCapabilitys used by this bundle wiring, or an empty list if this bundle wiring requires no capabilities in the specified name space. If this bundle wiring is not in use, null will be returned. The list contains the required capabilities in the order they are specified in the manifest. OSGi Javadoc -- 8/18/10 Page 29 of 41

35 Interface BundleWiring getbundlerevision BundleRevision getbundlerevision() Returns the bundle revision for the bundle in this bundle wiring. Since a bundle update can change the entries in a bundle, different bundle wirings for the same bundle can have different bundle revisions. The bundle object referenced by the returned BundleRevision may return different information than the returned BundleRevision since the returned BundleRevision may refer to an older revision of the bundle. Returns: The bundle revision for this bundle wiring. getfragmentrevisions List<BundleRevision> getfragmentrevisions() Returns the bundle revisions for all attached fragments of this bundle wiring. Since a bundle update can change the entries in a fragment, different bundle wirings for the same bundle can have different bundle revisions. The bundle revisions in the list are ordered in fragment attachment order such that the first revision in the list is the first attached fragment and the last revision in the list is the last attached fragment. Returns: A list containing a snapshot of the BundleRevisions for all attached fragments attached of this bundle wiring, or an empty list if this bundle wiring does not have any attached fragments. If this bundle wiring is not in use, null will be returned. getclassloader ClassLoader getclassloader() Returns the class loader for this bundle wiring. Since a bundle refresh creates a new bundle wiring for a bundle, different bundle wirings for the same bundle will have different class loaders. Returns: The class loader for this bundle wiring. If this bundle wiring is not in use, null will be returned. Throws: SecurityException - If the caller does not have the appropriate RuntimePermission("getClassLoader"), and the Java Runtime Environment supports permissions. findentries List<URL> findentries(string path, String filepattern, int options) Returns entries in this bundle wiring's bundle revision and its attached fragment revisions. This bundle wiring's class loader is not used to search for entries. Only the contents of this bundle wiring's bundle revision and its attached fragment revisions are searched for the specified entries. This method takes into account that the "contents" of this bundle wiring can have attached fragments. This "bundle space" is not a namespace with unique members; the same entry name can be present multiple times. This method therefore returns a list of URL objects. These URLs can come from different JARs but OSGi Javadoc -- 8/18/10 Page 30 of 41

36 Interface BundleWiring have the same path name. This method can either return only entries in the specified path or recurse into subdirectories returning entries in the directory tree beginning at the specified path. Note: Jar and zip files are not required to include directory entries. URLs to directory entries will not be returned if the bundle contents do not contain directory entries. Parameters: path - The path name in which to look. The path is always relative to the root of this bundle wiring and may begin with "/". A path value of "/" indicates the root of this bundle wiring. filepattern - The file name pattern for selecting entries in the specified path. The pattern is only matched against the last element of the entry path. If the entry is a directory then the trailing "/" is not used for pattern matching. Substring matching is supported, as specified in the Filter specification, using the wildcard character ("*"). If null is specified, this is equivalent to "*" and matches all files. options - The options for listing resource names. See FINDENTRIES_RECURSE. The method must ignore unrecognized options. Returns: An unmodifiable list of URL objects for each matching entry, or an empty list if no matching entry could not be found or if the caller does not have the appropriate AdminPermission[bundle,RESOURCE] and the Java Runtime Environment supports permissions. The list is ordered such that entries from the bundle revision are returned first followed by the entries from attached fragment revisions in attachment order. If this bundle wiring is not in use, null will be returned. See Also: org.osgi.framework.bundle.findentries(string, String, boolean) listresources List<String> listresources(string path, String filepattern, int options) Returns the names of resources visible to this bundle wiring's class loader. The returned names can be used to access the resources via this bundle wiring's class loader. Parameters: path - The path name in which to look. The path is always relative to the root of this bundle wiring's class loader and may begin with "/". A path value of "/" indicates the root of this bundle wiring's class loader. filepattern - The file name pattern for selecting resource names in the specified path. The pattern is only matched against the last element of the resource path. If the resource is a directory then the trailing "/" is not used for pattern matching. Substring matching is supported, as specified in the Filter specification, using the wildcard character ("*"). If null is specified, this is equivalent to "*" and matches all files. options - The options for listing resource names. See LISTRESOURCES_LOCAL and LISTRESOURCES_RECURSE. The method must ignore unrecognized options. Returns: An unmodifiable list of resource names for each matching resource, or an empty list if no matching resource could not be found or if the caller does not have the appropriate AdminPermission[bundle,RESOURCE] and the Java Runtime Environment supports permissions. The list is ordered such that resource names from this bundle are returned in the order they are visible in this bundle wiring's class loader. If this bundle wiring is not in use, null will be returned. OSGi Javadoc -- 8/18/10 Page 31 of 41

37 Interface BundleWirings Interface BundleWirings org.osgi.framework.wiring All Superinterfaces: org.osgi.framework.bundlereference public interface BundleWirings extends org.osgi.framework.bundlereference The in use bundle wirings for a bundle. Each time a bundle is resolved, a new bundle wiring of the bundle is created. A bundle wiring consists of a bundle and its attached fragments and represents the dependencies with other bundle wirings. The in use bundle wirings for a bundle can be obtained by calling bundle.adapt(bundlewirings.class). getwirings(). Version: $Id: ecf3e a6710f4dff063577bd052f5dafe2 $ ThreadSafe Method Summary List<Bundl ewiring> getwirings() Return the in use wirings for the referenced bundle. Pag e 32 Methods inherited from interface org.osgi.framework.bundlereference getbundle Method Detail getwirings List<BundleWiring> getwirings() Return the in use wirings for the referenced bundle. If the referenced bundle is a non-fragment bundle, then the result is a list of in use bundle wirings. The list is ordered in reverse chronological order such that the first bundle wiring is the current bundle wiring and last wiring is the oldest in use bundle wiring. If the referenced bundle is a fragment bundle, then the result is a list of in use bundle wirings to which the referenced fragment bundle is attached. The ordering of the list is unspecified. If the fragment bundle is not attached to any bundle wiring, then the returned list will be empty. The list must only contain in use bundle wirings. Generally the list will have at least one bundle wiring for the bundle: the current bundle wiring. However, for an uninstalled bundle with no in use bundle wirings or a newly installed bundle which has not been resolved, the list will be empty. Returns: A list containing a snapshot of the BundleWirings for the referenced bundle. OSGi Javadoc -- 8/18/10 Page 32 of 41

38 Interface Capability Interface Capability org.osgi.framework.wiring All Known Subinterfaces: WiredCapability public interface Capability A capability that has been declared from a bundle revision. The framework defines capabilities for packages and bundles. Version: $Id: 0ea57aa9a6c8c6ad99cbf918d42b77e $ ThreadSafe Field Summary String String BUNDLE_CAPABILITY Capability name space for bundle capabilities. PACKAGE_CAPABILITY Capability name space for package capabilities. Method Summary Map<String,Object> Map<String,String> String BundleRevi sion getattributes() Returns the attributes of this capability. getdirectives() Returns the directives of this capability. getnamespace() Returns the name space of this capability. getproviderrevision() Returns the bundle revision declaring this capability. Pag e Pag e Field Detail PACKAGE_CAPABILITY public static final String PACKAGE_CAPABILITY = "osgi.package" Capability name space for package capabilities. The name of the package is stored in the capability attribute of the same name as this name space. The other directives and attributes of the package, from the Export-Package manifest header, can be found in the cabability's directives and attributes. The version capability attribute must contain the org.osgi.framework.version of the package if one is specified. The bundle-symbolic-name capability attribute must contain the symbolic name of the provider if one is specified. The bundle-version capability attribute must contain the version of the provider if one is specified. The package capabilities provided by the system bundle, that is the bundle with id zero, must include the package specified by the org.osgi.framework.constants.framework_systempackages and org.osgi.framework.constants.framework_systempackages_extra framework properties as well as any other package exported by the framework implementation. A bundle revision declares zero or more package capabilities (this is, exported packages). OSGi Javadoc -- 8/18/10 Page 33 of 41

39 Interface Capability A bundle wiring provides zero or more resolved package capabilities (that is, exported packages) and requires zero or more resolved package capabilities (that is, imported packages). The number of package capabilities required by a bundle wiring may change as the bundle wiring may dynamically import additional packages. BUNDLE_CAPABILITY public static final String BUNDLE_CAPABILITY = "osgi.bundle" Capability name space for bundle capabilities. The bundle symbolic name of the bundle is stored in the capability attribute of the same name as this name space. The other directives and attributes of the bundle, from the Bundle-SymbolicName manifest header, can be found in the cabability's directives and attributes. The bundle-version capability attribute must contain the org.osgi.framework.version of the bundle, from the Bundle-Version manifest header. A bundle wiring provides exactly one bundle capability (that is, the bundle can be required by another bundle) and requires zero or more bundle capabilities (that is, requires other bundles). A bundle with no bundle symbolic name (that is, a bundle with Bundle-ManifestVersion< 2) must not provide a bundle capability. Method Detail getnamespace String getnamespace() Returns the name space of this capability. Returns: The name space of this capability. getdirectives Map<String,String> getdirectives() Returns the directives of this capability. Returns: An unmodifiable map of directive names to directive values for this capability, or an empty map if this capability has no directives. getattributes Map<String,Object> getattributes() Returns the attributes of this capability. Returns: An unmodifiable map of attribute names to attribute values for this capability, or an empty map if this capability has no attributes. OSGi Javadoc -- 8/18/10 Page 34 of 41

40 Interface Capability getproviderrevision BundleRevision getproviderrevision() Returns the bundle revision declaring this capability. Returns: The bundle revision declaring this capability. OSGi Javadoc -- 8/18/10 Page 35 of 41

41 Interface FrameworkWiring Interface FrameworkWiring org.osgi.framework.wiring All Superinterfaces: org.osgi.framework.bundlereference public interface FrameworkWiring extends org.osgi.framework.bundlereference Query and modify wiring information for the framework. The framework wiring object for the framework can be obtained by calling bundle.adapt(frameworkwiring.class) on the system bundle. Only the system bundle can be adapted to a FrameworkWiring object. The system bundle associated with this FrameworkWiring object can be obtained by calling org.osgi.framework.bundlereference.getbundle(). Version: $Id: f9f3f89b5b8d369453d645a52a482a385a2bd520 $ ThreadSafe Method Summary Collection <org.osgi. framework. Bundle> Collection <org.osgi. framework. Bundle> void boolean getdependencyclosure(collection<org.osgi.framework.bundle> bundles) Returns the dependency closure for the specified bundles. 38 getremovalpendingbundles() Returns the bundles that have non-current, in use bundle wirings. 38 refreshbundles(collection<org.osgi.framework.bundle> bundles, org.osgi.framework.frameworklistener... listeners) Refreshes the specified bundles. resolvebundles(collection<org.osgi.framework.bundle> bundles) Resolves the specified bundles. Pag e Methods inherited from interface org.osgi.framework.bundlereference getbundle Method Detail refreshbundles void refreshbundles(collection<org.osgi.framework.bundle> bundles, org.osgi.framework.frameworklistener... listeners) Refreshes the specified bundles. This forces the update (replacement) or removal of packages exported by the specified bundles. The technique by which the framework refreshes bundles may vary among different framework implementations. A permissible implementation is to stop and restart the framework. This method returns to the caller immediately and then performs the following steps on a separate thread: 1. Compute the dependency closure of the specified bundles. If no bundles are specified, compute the dependency closure of the removal pending bundles. 2. Each bundle in the dependency closure that is in the ACTIVE state will be stopped as described in the Bundle.stop method. OSGi Javadoc -- 8/18/10 Page 36 of 41

42 Interface FrameworkWiring 3. Each bundle in the dependency closure that is in the RESOLVED state is unresolved and thus moved to the INSTALLED state. The effect of this step is that bundles in the dependency closure are no longer RESOLVED. 4. Each bundle in the dependency closure that is in the UNINSTALLED state is removed from the dependency closure and is now completely removed from the Framework. 5. Each bundle in the dependency closure that was in the ACTIVE state prior to Step 2 is started as described in the Bundle.start method, causing all bundles required for the restart to be resolved. It is possible that, as a result of the previous steps, packages that were previously exported no longer are. Therefore, some bundles may be unresolvable until bundles satisfying the dependencies have been installed in the Framework. For any exceptions that are thrown during any of these steps, a framework event of type FrameworkEvent.ERROR is fired containing the exception. The source bundle for these events should be the specific bundle to which the exception is related. If no specific bundle can be associated with the exception then the System Bundle must be used as the source bundle for the event. All framework events fired by this method are also delivered to the specified FrameworkListeners in the order they are specified. When this process completes after the bundles are refreshed, the Framework will fire a Framework event of type FrameworkEvent.PACKAGES_REFRESHED to announce it has completed the bundle refresh. The specified FrameworkListeners are notified in the order specified. Each specified FrameworkListener will be called with a Framework event of type FrameworkEvent.PACKAGES_REFRESHED. Parameters: bundles - The bundles to be refreshed, or null to refresh the removal pending bundles. listeners - Zero or more listeners to be notified when the bundle refresh has been completed. The specified listeners do not need to be otherwise registered with the framework. If a specified listener is already registered with the framework, it will be notified twice. Throws: IllegalArgumentException - If the specified Bundles were not created by the same framework instance associated with this FrameworkWiring. SecurityException - If the caller does not have AdminPermission[System Bundle,RESOLVE] and the Java runtime environment supports permissions. resolvebundles boolean resolvebundles(collection<org.osgi.framework.bundle> bundles) Resolves the specified bundles. The Framework must attempt to resolve the specified bundles that are unresolved. Additional bundles that are not included in the specified bundles may be resolved as a result of calling this method. A permissible implementation of this method is to attempt to resolve all unresolved bundles installed in the framework. If no bundles are specified, then the Framework will attempt to resolve all unresolved bundles. This method must not cause any bundle to be refreshed, stopped, or started. This method will not return until the operation has completed. Parameters: bundles - The bundles to resolve or null to resolve all unresolved bundles installed in the Framework. Returns: true if all specified bundles are resolved; false otherwise. Throws: IllegalArgumentException - If the specified Bundles were not created by the same framework instance associated with this FrameworkWiring. SecurityException - If the caller does not have AdminPermission[System Bundle,RESOLVE] and the Java runtime environment supports permissions. OSGi Javadoc -- 8/18/10 Page 37 of 41

43 Interface FrameworkWiring getremovalpendingbundles Collection<org.osgi.framework.Bundle> getremovalpendingbundles() Returns the bundles that have non-current, in use bundle wirings. This is typically the bundles which have been updated or uninstalled since the last call to refreshbundles(collection, FrameworkListener...). Returns: A collection containing a snapshot of the Bundles which have non-current, in use BundleWirings, or an empty collection if there are no such bundles. getdependencyclosure Collection<org.osgi.framework.Bundle> getdependencyclosure(collection<org.osgi.framework.bundl e> bundles) Returns the dependency closure for the specified bundles. A graph of bundles is computed starting with the specified bundles. The graph is expanded by adding any bundle that is either wired to a package that is currently exported by a bundle in the graph or requires a bundle in the graph. The graph is fully constructed when there is no bundle outside the graph that is wired to a bundle in the graph. The graph may contain UNINSTALLED bundles that are removal pending. Parameters: bundles - The initial bundles for which to generate the dependency closure. Returns: A collection containing a snapshot of the dependency closure of the specified bundles, or an empty collection if there were no specified bundles. Throws: IllegalArgumentException - If the specified Bundles were not created by the same framework instance associated with this FrameworkWiring. OSGi Javadoc -- 8/18/10 Page 38 of 41

44 Interface WiredCapability Interface WiredCapability org.osgi.framework.wiring All Superinterfaces: Capability public interface WiredCapability extends Capability A wired capability that has been provided from a bundle wiring. This capability may or may not be required by any bundle wiring. A wired capability represents a capability from a resolved bundle wiring. Version: $Id: bdf793be0ba691b543c523ca1b608e356aac9963 $ ThreadSafe Fields inherited from interface org.osgi.framework.wiring.capability BUNDLE_CAPABILITY, PACKAGE_CAPABILITY Method Summary BundleWiri ng Collection <BundleWir ing> getproviderwiring() Returns the bundle wiring providing this capability. getrequirerwirings() Returns the bundle wirings that require this capability. Pag e Methods inherited from interface org.osgi.framework.wiring.capability getattributes, getdirectives, getnamespace, getproviderrevision Method Detail getproviderwiring BundleWiring getproviderwiring() Returns the bundle wiring providing this capability. Returns: The bundle wiring providing this capability. If the bundle wiring providing this capability is not in use, null will be returned. getrequirerwirings Collection<BundleWiring> getrequirerwirings() Returns the bundle wirings that require this capability. The result of this method can change if this capability becomes required by additional bundle wirings. OSGi Javadoc -- 8/18/10 Page 39 of 41

45 Interface WiredCapability Returns: A collection containing a snapshot of the bundle wirings currently requiring this capability, or an empty collection if no bundle wirings require this capability. If the bundle wiring providing this capability is not in use, null will be returned. Java API documentation generated with DocFlex/Doclet v1.5.6 DocFlex/Doclet is both a multi-format Javadoc doclet and a free edition of DocFlex/Javadoc. If you need to customize your Javadoc without writing a full-blown doclet from scratch, DocFlex/Javadoc may be the only tool able to help you! Find out more at 7 Command Line API Command line API is not considered relevant to this design. Hooks are a very low level concept which should not be accessed by the command line. 8 JMX API JMX API is not considered relevant to this design. Hooks are a very low level concept which should not be accessed by JMX. 9 Considered Alternatives The list of alternatives is too long and painful to list. Take a look at the document history to see the long and painful journey up to this point. OSGi Javadoc -- 8/18/10 Page 40 of 41

46 Interface WiredCapability 10 Security Considerations When Java permissions are in effect, this design is secured by ServicePermissions. The bundle registering the various hook services must have the necessary ServicePermission.REGISTER. Since there are various hook services, we have fine grained control over what specific hooks a bundle can register. 11 Document Support 11.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN Author s Address Name Company Thomas Watson IBM Corporation Address Voice [email protected] 11.3 Acronyms and Abbreviations 11.4 End of Document OSGi Javadoc -- 8/18/10 Page 41 of 41

47 RFC Generic Capabilities & Requirements Page 1 of 17 Final September 2, 2010 RFC Generic Capabilities & Requirements Final 17 Pages Abstract This document proposes an approach for bundles to declare generic capabilities and for other bundles specify requirements on those capabilities. Copyright Oracle 2010

48 RFC Generic Capabilities & Requirements Page 2 of 17 Final September 2, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Problem Description Extender bundle dependencies Operating environment dependencies (Bug 282) Limitations of Bundle-RequiredExecutionEnvironment Inability to capture java.* dependencies (Bug 390) Lack of expressiveness (Bug 1000) Native code dependencies (Bug 1013) Requirements Technical Solution General approach Optionality Effective time Management Agents Resolution result Multiple matching providers Cardinality of requirements Capability/Requirement verification Host/fragment conflicts Considered Alternatives Discovery Uses constraints Singleton capabilities Mappings for existing headers Bundle state related capabilities Copyright Oracle 2010

49 RFC Generic Capabilities & Requirements Page 3 of 17 Final September 2, Security Considerations Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in 8.1. Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial Dec. 14 th, 2009 Southampton F2F feedback Bundle state feedback Mountview F2F feedback London F2F feedback Mar. 1 st, 2010 Mar 16 th 2010 May 13 th, 2010 June 1 st, 2010 Adopted typed attribute approach. Resolve result is now observable with lifecycle coupling. Added wording on multiple matching providers, capability/requirement verification, and existing header mappings. Added framework property that controls which capability namespaces get processed by the framework and commentary on bundle state related capabilities Rolled back the prior changes, added language to indicate the resolvetime scope of the solution, and added initial requirements. Add effective time directive and adjusted scope discussion accordingly RFC 151 July 23 rd, 2010 Added a simple comment to tie this RFC to RFC 151 for purposes of an API for reflecting on wiring. Ottawa F2F feedback CPEG call feedback August 25 th, 2010 August 30 th, 2010 Added uses directive, added List attribute type, and more namespace clarifications. Added note about case sensitivity, defined List syntax, clarified some host/fragment issues, added permission. Final Draft 09/02/10 Updated the grammar for the manifest headers to be more in line with existing specified manifest headers. Copyright Oracle 2010

50 RFC Generic Capabilities & Requirements Page 4 of 17 Final September 2, Introduction The OSGi specification defines a handful of different dependency types that can exist among bundles, such as package, bundle, and fragment dependencies. All of these dependencies relate to defining code visibility for the involved bundles. The OSGi framework is able to consistently resolve these dependencies to ensure a given bundle's code dependencies are satisfied so it can be used successfully. While this approach is certainly important and worthwhile, it does have one significant drawback. Not all dependencies among bundles are related to code visibility. A prime example are bundles requiring specific capabilities from the underlying platform, such as particular hardware devices or windowing toolkit. Since the target of the dependency is not manifested as a bundle, there is no proper way to express such dependencies. It would be worthwhile if the framework and bundles could declare that they provide some arbitrary capability and other bundles could declare requirements on those capabilities. This RFC investigates this issue and proposes a simple manifest-based metadata approach for declaring dependencies among bundles for reasons other than code visibility. 2 Application Domain This RFC intends to provide a generic dependency model for bundles that will be understood and enforced by the resolver. Since existing resolve-time dependencies are related to code visibility management, the resolution of such dependencies and the RESOLVED bundle life cycle state have traditionally indicated that the bundles in question are ready to share and/or use their code. With a generic dependency model, this meaning is stretched to some degree. Further, some dependencies are explicitly or implicitly tied to the ACTIVE bundle life cycle state and are not actually ready at resolve-time. For example, service dependencies require that both the provider and consumer components are ACTIVE for them to be ready, while extender/extendee dependencies typically require (at a minimum) the extender bundle to be ACTIVE for them to be ready. This RFC is intended to address static dependencies and not these sorts of active dependencies. However, since this is a generic dependency module, it is difficult, if not impossible, to limit its application to static dependencies. As such, this RFC will attempt to differentiate between static and active dependencies, but will only be able to enforce static ( i.e., resolve-time dependencies). The main impacts of modeling active dependencies with this mechanism are pushing the dependency resolution earlier in the bundle life cycle than what is strictly necessary and effectively concluding that the bundles are ready before they can technically be ready. The former impact cannot be avoided and typically results in having to deploy more bundles up front to resolve all dependencies at resolve time. The second impact can effectively be addressed by layering additional mechanisms on top to transition bundles to their appropriate states based on more detailed knowledge about their active dependencies. Copyright Oracle 2010

51 RFC Generic Capabilities & Requirements Page 5 of 17 Final September 2, Problem Description While bundles are able to express a variety of code-related dependencies, not all bundle dependencies are related to code. Ultimately, this leads to situations where a bundle is unable to properly function, even though its code-related dependencies have been properly satisfied. Defining a standard way to express non-code-related dependencies will help eliminate such situations. The following use cases illustrate where such a mechanism could be applicable. 3.1 Operating environment dependencies (Bug 282) It is often required to have one configuration of bundles run in multiple different operating environments. Here an operating environment is comprised largely of the OS, windowing system, locale, and processor architecture. In certain situations, such as on Unix systems that support GTK and Motif or when the user wants to run the same configuration on a different machine, these capabilities can vary greatly. Currently, bundles are unable to state the operating environment in which they are valid, this is left to an external management agent to uninstall/reinstall bundles as appropriate. This sets up a need to communicate somehow with an agent on startup or requires managing multiple configurations. It also makes it difficult for provisioning agents to know which bundles are valid for which platforms. 3.2 Limitations of Bundle-RequiredExecutionEnvironment Inability to capture java.* dependencies (Bug 390) Sometimes bundle execution environment dependencies do not fall neatly into the defined set of execution environments. For example, consider the follow situations: a bundle that bundle limits itself to the APIs available in the Foundation 1.0 execution environment, but it finds it also needs the java.beans package. While it is possible to install a boot class path extension bundle to supply java.beans, the bundle in question has no way to indicate that it needs the extension bundle in the first place Lack of expressiveness (Bug 1000) In some cases it may make sense to prohibit a bundle on a higher level VM. Currently, this is not possible with BREE because it specifies a list of EEs that the bundle is compatible with. For example: Bundle-RequiredExecutionEnvironment: J2SE-1.4 This means the bundle requires an EE that is compatible with J2SE-1.4. This includes J2SE-1.5, JavaSE-1.6 and all future VMs that will be compatible with J2SE-1.4. In some cases, it may make sense to provide a range limit to the EEs that the bundle can execute on. Something like this: Bundle-RequiredExecutionEnvironment: [J2SE-1.3, J2SE-1.5) This would specify that the bundle can execute on an EE that is compatible with J2SE-1.3, J2SE-1.4 but can not execute on an EE that is compatible with J2SE-1.5 or higher. Copyright Oracle 2010

52 3.3 Native code dependencies (Bug 1013) RFC Generic Capabilities & Requirements Page 6 of 17 Final September 2, 2010 The OSGi framework supports direct bundle dependencies on native code, but it is unable to deal with dependencies from one native library to another. While there is not a perfect solution to this issue, one approach to lessen the impact would be to devise a new system bundle fragment which could install native libraries in the LD_LIBRARY_PATH so that dependencies between native libraries could be resolved. However, a bundle would need some way to express a dependency on such native system bundle fragments if it were required for it to function properly. 3.4 Extender bundle dependencies The extender pattern is a common OSGi pattern for providing some functionality or performing some task for unknowing bundles. An extender bundle listens for bundle lifecycle events, probes the associated bundles for metadata, then performs some activity on behalf of the bundle or some other purpose. The extendee bundle may have been written to explicitly expect the processing of the extender and may not be able to properly function without it. If the extendee bundle does not have a code dependency on the extender, then it has no way to express this requirement. Technically, this is an active dependency and can only be partially addressed by this RFC when modeled as a static dependency. 4 Requirements REQ01 REQ02 REQ03 REQ04 REQ05 The solution MUST provide a way to capture dependencies among bundles not related to code visibility. The solution MUST provide a way to capture dependencies between bundles and the underlying platform/execution environment. The solution MUST be verifiable by the resolver without significant additional overhead. The solution MUST be limited to resolve-time enforcement/verification of dependencies. The solution MUST differentiate between static dependencies (i.e., resolve-time) versus active dependencies (i.e., active-time). Copyright Oracle 2010

53 RFC Generic Capabilities & Requirements Page 7 of 17 Final September 2, Technical Solution This RFC proposes additional manifest headers for bundles to declare arbitrary provided capabilities and requirements on them. These headers impact resolution of the bundles involved and the dependencies among them, but have no other impact. To state this in another way using an analogy, while the resolver can be seen as injecting code visibility wires into a bundle or a service dependency framework can be seen as injecting services into a component, the mechanism proposed in this document only injects dependencies among bundles, but does not grant access to any capability as a result of this injection. It is predicated solely on the existence of declared capabilities to satisfy declared requirements and nothing more. 5.1 General approach The general approach uses manifest-based syntax to allow a bundle to declare arbitrary capabilities and requirements. A capability is a set of attributes associated with a given namespace, where the namespace is simply a string name used to scope attribute names to avoid name clashes and convey semantics. For example, in OBR's use of generic capabilities and requirements, it uses the package and bundle namespaces to map package and bundle code dependencies, respectively. The namespace syntax is limited to the same construction rules as bundle symbolic names (i.e., dot-delimited strings). The specification reserves the osgi.* namespace for its own purposes. Comparisons for namespaces and attribute names are case sensitive. The approach for declaring a dependency uses the common OSGi manifest header syntax, since it avoids the need for new parsing code. To declare a capability, the Provide-Capability header is used, which has the following syntax: Provide-Capability ::= capability ( ',' capability )* capability ::= namespace ( ';' ( directive attribute typed-attribute ) )* namespace ::= symbolic-name typed-attribute ::= token ':' ( ( scalar-type '=' argument ) ( list-type '=' list-argument ) ) scalar-type ::= 'String' 'Version' 'Long' 'Double' list-type ::= 'List' ( '<' scalar-type '>' )? list-argument ::= '"' list-string ( ',' list-string )* '"' list-string ::= ( [^",\#x0d#x0a#x00] '\"' '\,' '\\')* Supported directives are "effective", with values of "resolve" and "active", and "uses", with value of a commaseparated list of package names. The effective directive is used to indicate at which time the capability is in effect. The solution proposed by this RFC will only consider capabilities with effective time resolve; all other capabilities are ignored. If the effective directive is not specified, then resolve is assumed. The uses directive for generic capabilities has the same meaning as defined for the Export-Package header. Specifically, it is a comma-delimited list of package names on which the associated generic capability depends. The specified package names are ones either exported or imported by the bundle providing the generic capability; if not, then it is ignored. It is not possible to specify uses constraints on arbitrary generic capabilities, only on packages. Copyright Oracle 2010

54 RFC Generic Capabilities & Requirements Page 8 of 17 Final September 2, 2010 The presence of the uses directive on a generic capability causes the resolver to place an additional constraint on any bundles requiring it. The additional constraint requires that if they also import a package used by the generic capability, then they must get it from the same source as the bundle providing the generic capability. It is not possible to make generic uses constraints transitive. For example, with packages you can specify a uses constraints on your exported package to an imported package; doing so makes the uses constraints from the provider of the imported package apply to importers of the original exported package (i.e., they are transitive). The analog is not possible with generic capabilities. Uses constraints cannot be transitive across generic requirements on generic capabilities, since it is not possible to refer to generic requirements in the uses constraint of a generic capability. An example capability is: Provide-Capability: foo-extender; version:version="1.1.0"; secure=false An untyped attribute defaults to String type. An attribute of type List may also include a component type declaration as well as a comma-delimited list of values, such as: versions:list<version>="1.0.0,1.0.1" If the component type is omitted, then it defaults to String. If the value of a list element must include quotes or commas, then they must be escaped with a backslash. If there is leading or trailing whitespace in the elements of the value string and the component type is Long, Double, or Version, then the whitespace is trimmed; otherwise it is significant. To require a generic capability, the Require-Capability header is used, which has the following syntax: Require-Capability ::= requirement ( ',' requirement )* requirement ::= namespace ( ';' parameter )* namespace ::= symbolic-name Supported directives are "effective", with values of "resolve" and "active", and "resolution", with values of mandatory and optional. The only supported attribute is filter. The filter attribute must be specified and its value must be a quoted-string containing a filter string (see in spec) to match against provided capabilities. Since the filter attribute value is a quoted-string and the manifest parser will convert \\ to \, if the filter string needs to escape characters for the filter processor (for example ')'; see in spec), then a double backslash will be need in the manifest to end up with a single backslash in the resulting filter string after manifest parsing. The effective directive is used to indicate at which time the requirement is in effect. The solution proposed by this RFC will only enforce/verify requirements with effective time resolve; all other requirements are ignored. If the effective directive is not specified, then resolve is assumed. The resolution directive is used to indicate whether a requirement is mandatory or optional, following the same semantics as optional imports. An example requirement for some imaginary extender bundle is: Require-Capability: foo-extender; filter="(&(version>=1.0.0)(!(version>=2.0.0))(secure=true))" Copyright Oracle 2010

55 RFC Generic Capabilities & Requirements Page 9 of 17 Final September 2, 2010 For this imaginary example, the requirement would not match the capability. Even though the extender is within the required version range, it does not provide a secure capability. There is no concept of substitutable capabilities like we have for exported packages. Therefore, there is no special meaning placed on a bundle providing and requiring a given capability namespace, even if it matches itself. Such occurrences are treated as independently and are specifically allowed to match each other, which may be necessary if a fragment supplies something needed by a host. 5.2 Optionality By default, all requirements are mandatory. However, Require-Capability does support the resolution directive which can be used to declare a requirement as optional. 5.3 Effective time The default effective time of generic capabilities and requirements is at bundle resolve time, the same as for any of the existing code dependencies. The resolver algorithm only runs at resolve time, except in the cases of dynamically imported packages. In the case of generic capabilities and requirements, there does not appear to be an analogue to dynamically imported packages. The resolver will only match a generic requirement to a capability if both have an effective time of resolve, since the framework ignores requirements and capabilities with any other effective time. On the other hand, upper layers are free to match active requirements to resolve capabilities. 5.4 Resolution result The result of resolving generic capabilities and requirements is a set of wires. A wire connects a given requirement to its satisfying provider(s). The wiring result does not imply any sort of additional visibility or grant any new functionality between the provider and requirers. It does, however, tie their life cycles together like normal package wiring. This means if the provider is refreshed, then requiring bundles are refreshed as well. RFC 151 is refactoring the Package Admin API and is providing an API for reflecting over bundle dependencies in a generic way, which will encompass reflecting over the resulting RFC 154 dependencies. Note that RFC 151 maps existing capabilities and requirements (e.g., packages, bundles, etc.) into this generic model for reflective purposes. As a result, it creates specific namespaces under osgi. that may be illegal to directly specify in the manifest. For example, it is not possible to use the osgi.package namespace to export or import a package. An installation exception will be thrown for any bundle specifying a non-allowed OSGi namespace in its manifest. 5.5 Multiple matching providers If multiple providers match a given requirement, then similar rules as for multiple packages providers are followed. For example: 1. A resolved provider is preferred over an unresolved one. 2. Lower bundle identifier is preferred over a higher one. A difference is that we do not assume anything about versioning for generic providers, 5.6 Cardinality of requirements All generic requirements are assumed to match only a single provider. Copyright Oracle 2010

56 5.7 Capability/Requirement verification RFC Generic Capabilities & Requirements Page 10 of 17 Final September 2, 2010 Unlike other headers (e.g., Import-Package and Export-Package) that have various verification rules associated with them (i.e., cannot duplicate or have certain attributes), generic capabilities/requirements have no such verification phase. So, for example, there is no way to say a bundle can only provide a given capability once or require overlapping providers. 5.8 Host/fragment issues For code-related dependencies, fragment capabilities and requirements are merged with the host as long as they do not conflict. It is not clear how to detect a conflict for generic capabilities/requirements; thus, it is assumed that generic capabilities/requirements supplied by a fragment never conflict with those of a host. Any fragment capabilities that are attached to a host bundle will appears as if they come from the host bundle after attachment. This is necessary since fragments can attach to multiple hosts, which effectively makes them different providers with respect to uses constraints. 6 Considered Alternatives 6.1 Discovery OBR has demonstrated the potential usefulness of using generic requirements to aide in the discovery of interesting or related functionality. OBR refers to this as an extends relationship, which indicates that a given resource extends another target resource, although the target resource is unaware of it. Currently in OBR, this is simply represented as a requirement with a boolean extends flag. Having such a concept makes it possible for an OBR resolver implementation to proactively discover related resources and to implement policies around such extensions. It would be possible to support such a concept here with a directive on Require-Capability. 6.2 Uses constraints It is not clear if uses constraints can be applied in a generic context. 6.3 Singleton capabilities Yuck. We don't support them. 6.4 Mappings for existing headers The existing bundle manifest headers could easily be mapped to this generic approach and in the case of OBR, they will be. Currently, the framework will not consider such replacements for the existing headers. Copyright Oracle 2010

57 6.5 Bundle state related capabilities. RFC Generic Capabilities & Requirements Page 11 of 17 Final September 2, 2010 Framework level handling of bundle state issues was ruled out on complexity grounds. Whether it is possible and or desirable is an open question. One option was to define a set of well known capability attributes that indicate the bundle state in which capability is available. One option was to drop active state related capabilities from this specification altogether and make a statement that it should not be used to model these. The view seems to be that the informative resolution time error message makes modeling them in this way worthwhile. 6.6 Management agent control of namespaces The effective time of all capabilities is bundle resolution time and this has some downsides for capabilities where bundle state matters. Although addressing this in a standardized way at framework level would be complex, or at least premature, management agents that deal with bundle provisioning should not be prevented from innovating in this area. For example, a management agent may know that a resolved extendee bundle has no need for a resolved extender bundle, and may also know that before the extendee is activated the extender should also be active. In this case the management agent will want to take responsibility for handling the extender capability and would like the framework to ignore it. To this end the solution will make use of a framework property that tells the framework which capability namespaces it should ignore, as follows. org.osgi.framework.processcapabilites = '-*' * (-)?namespace(,namespace)* Where namespace is a generic capability namespace. If the value is * then the framework will process all namespaces. This is the default. In the absence of a leading '-', the list comprises the namespaces that the framework should process. All others should be ignored. If the value is '-*' then the framework should ignore all namespaces. If the value has a leading '-' then the listed namespaces should be ignored by the framework, but all others should be processed. Copyright Oracle 2010

58 RFC Generic Capabilities & Requirements Page 12 of 17 Final September 2, Security Considerations The following permission is defined to control providing and requiring generic capabilities. For standard capabilities provided by the framework, the framework will need to implicitly grant bundle's the necessary CapabilityPermission to require those capabilities. Copyright Oracle 2010

59 Class CapabilityPermission Class CapabilityPermission org.osgi.framework java.lang.object java.security.permission java.security.basicpermission All Implemented Interfaces: Guard, Serializable org.osgi.framework.capabilitypermission final public class CapabilityPermission extends BasicPermission A bundle's authority to provide or require a capability. The provide action allows a bundle to provide a capability matching the specified filter. The require action allows a bundle to require a capability matching the specified filter. Since: 1.6 Version: $Id: 11e47883a0c36de7cd69d d41f8bd30f17 $ ThreadSafe Field Summary static String static String PROVIDE The action string provide. REQUIRE The action string require. Pag e Constructor Summary CapabilityPermission(String name, String actions) Create a new CapabilityPermission. CapabilityPermission(String namespace, Map<String,?> attributes, Bundle providingbundle, String actions) Creates a new requested CapabilityPermission object to be used by code that must perform checkpermission for the require action. Method Summary boolean String int equals(object obj) Determines the equality of two CapabilityPermission objects. getactions() Returns the canonical string representation of the actions. hashcode() Returns the hash code value for this object. boolean implies(permission p) Determines if a CapabilityPermission object "implies" the specified permission. Permission Collection newpermissioncollection() Returns a new PermissionCollection object for storing CapabilityPermission objects. Pag e Pag e OSGi Javadoc -- 8/31/10 Page 13 of 17

60 Class CapabilityPermission Field Detail REQUIRE public static final String REQUIRE = "require" The action string require. PROVIDE public static final String PROVIDE = "provide" The action string provide. Constructor Detail CapabilityPermission public CapabilityPermission(String name, String actions) Create a new CapabilityPermission. The name is specified as a dot-separated string. Wildcards may be used. name ::= <namespace> <namespace ending in ".*"> * Examples: com.acme.capability.* org.foo.capability * For the require action, the name can also be a filter expression. The filter gives access to the capability attributes as well as the following attributes: signer - A Distinguished Name chain used to sign the bundle providing the capability. Wildcards in a DN are not matched according to the filter string rules, but according to the rules defined for a DN chain. location - The location of the bundle providing the capability. id - The bundle ID of the bundle providing the capability. name - The symbolic name of the bundle providing the capability. capability.namespace - The namespace of the required capability. Since the above attribute names may conflict with attribute names of a capability, you can prefix an attribute name with '@' in the filter expression to match against the capability attributes and not one of the above attributes. Filter attribute names are processed in a case sensitive manner. There are two possible actions: require and provide. The require permission allows the owner of this permission to require a capability matching the attributes. The provide permission allows the bundle to provide a capability in the specified capability namespace. Parameters: name - The capability namespace or a filter over the attributes. actions - require,provide (canonical order) Throws: IllegalArgumentException - If the specified name is a filter expression and either the specified action is not require or the filter has an invalid syntax. OSGi Javadoc -- 8/31/10 Page 14 of 17

61 Class CapabilityPermission CapabilityPermission public CapabilityPermission(String namespace, Map<String,?> attributes, Bundle providingbundle, String actions) Creates a new requested CapabilityPermission object to be used by code that must perform checkpermission for the require action. CapabilityPermission objects created with this constructor cannot be added to a CapabilityPermission permission collection. Parameters: namespace - The requested capability namespace. attributes - The requested capability attributes. providingbundle - The bundle providing the requested capability. actions - The action require. Throws: IllegalArgumentException - If the specified action is not require or any parameters are null. Method Detail implies public boolean implies(permission p) Determines if a CapabilityPermission object "implies" the specified permission. Overrides: implies in class BasicPermission Parameters: p - The target permission to check. Returns: true if the specified permission is implied by this object; false otherwise. getactions public String getactions() Returns the canonical string representation of the actions. Always returns present actions in the following order: require, provide. Overrides: getactions in class BasicPermission Returns: The canonical string representation of the actions. newpermissioncollection public PermissionCollection newpermissioncollection() Returns a new PermissionCollection object for storing CapabilityPermission objects. Overrides: newpermissioncollection in class BasicPermission Returns: A new PermissionCollection object suitable for storing CapabilityPermission objects. OSGi Javadoc -- 8/31/10 Page 15 of 17

62 Class CapabilityPermission equals public boolean equals(object obj) Determines the equality of two CapabilityPermission objects. Checks that specified object has the same name and action as this CapabilityPermission. Overrides: equals in class BasicPermission Parameters: obj - The object to test for equality. Returns: true if obj is a CapabilityPermission, and has the same name and actions as this CapabilityPermission object; false otherwise. hashcode public int hashcode() Returns the hash code value for this object. Overrides: hashcode in class BasicPermission Returns: Hash code value for this object. 8 Document Support 8.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN Author s Address Name Richard S. Hall Company Address Voice [email protected] 8.3 Acronyms and Abbreviations OSGi Javadoc -- 8/31/10 Page 16 of 17

63 Class CapabilityPermission 8.4 End of Document OSGi Javadoc -- 8/31/10 Page 17 of 17

64 RFC 159 Bytecode Weaving Final 42 Pages Abstract 10 point Arial Centered. This RFC describes the requirements and solution for providing bytecode weaving support in an OSGi framework. Copyright IBM 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

65 RFC 159 Bytecode Weaving Page 2 of 42 Final November 8, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Terminology + Abbreviations Problem Description Requirements Technical Solution The Weaving Service Basic load-time weaving support Error Handling More advanced load-time weaving support The Weaving Processing Weaving Service Javadoc Command Line API JMX API Considered Alternatives Bundle re-writing Woven Fragments The Weaving Service Load-time weaving support Class redefinition support Runtime retransformation support Weaving Service Javadoc Class redefinition support Runtime retransformation support Weaving Service Javadoc Security Considerations Copyright IBM 2010

66 RFC 159 Bytecode Weaving Page 3 of 42 Final November 8, Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial 06/21/10 Initial draft of the RFC /24/10 Update to Woven Fragments /03/10 Added the Weaving Service /10/10 After discussion on CPEG call, weaver lifecycle deemed to be more of an issue than scoping. Updated to use a whiteboard pattern for weavers 4 09/16/10 Discussed at Redwood F2F. Due to concerns about limited 4.3 release runway and the complexity of the problems in runtime weaving this RFC will be limited to load-time weaving and a new RFC created for runtime weaving. This RFC is still targeted for the 4.3 release. 5 10/08/10 Tom Watson 6 10/11/10 Tim Ward 7 10/27/10 Tim Ward Changes after CPEG call on 10/07/10 Updated Security section to reflect changes since 0.3 Finalized RFC draft before voting 8 11/08/10 Mark RFC final for voting. BJ Hargrave Copyright IBM 2010

67 RFC 159 Bytecode Weaving Page 4 of 42 Final November 8, Introduction There are several motivations for introducing this RFC. Bytecode weaving has become more popular, in particular due to its inclusion in the core Java API, and so there are a number of bytecode weaving technologies that would benefit from weaving support in the OSGi runtime. The primary technical driver for this RFC is to support the bytecode weaving model built in to the Java Persistence API[5]., however as there are numerous other technologies that make use of weaving, it is important that any solution be sufficiently general to be useful to a wider audience than JPA runtimes. A General introduction from the RFP follows: The Java TM Programming Language provides a full featured Object Oriented architecture for software development, and has grown dramatically over the years since its first release. A constant focus has been for Java TM applications to access advanced functionality with a minimum of programming effort. One of the original mechanisms by which this was achieved was for application classes to subclass a framework or API class and, either through direct method calls or xml metadata, make use of the super class's functionality. The primary disadvantage of this model is that it forces the application programmer to make certain design decisions, implement framework methods and drives the object model. In recent years there has been a significant change in the way programmers use Java TM. New programming models encourage the use of dependency injection and Plain Old Java Object (POJO) architectures. The aim of POJO programming models is to avoid having to add compile or runtime time dependencies on a framework. This greatly simplifies application development and allows application code to be tested outside of the application container. Obviously in order to support a POJO programming model an application framework still needs to hook into the application code, however there cannot be any hard dependencies without violating the principles of POJO programming. Many modern frameworks create these hook points using Aspect Oriented Programming (AOP) and bytecode weaving. AOP is typically used where a cross-cutting concern; for example transactions, security or tracing; can be identified, and needs to be applied across a number of methods and classes. It allows for a high degree of code reuse by defining a single piece of code (advice) that can be inserted into multiple class/methods (point-cuts). Bytecode weaving is the mechanism by which AOP is typically realised. A bytecode weaver processes a Java class file and some additional metadata (which may be included as Java TM annotations inside the class file) and writes a new version of the class including the woven aspects. There are two main strategies for bytecode weaving, known as Static Weaving and Dynamic Weaving. In static weaving woven advice is directly inserted at arbitary points in the class. This woven advice is usually very difficult to separate from the original bytecode of the class, but as it is written directly into the class there is a very low impact on performance. Dynamic Weaving differs from Static Weaving in that the woven aspect is typically abstracted from the point-cuts into which it is injected. This means that there are runtime objects representing the various aspects and point-cuts in the system, which can be used to add, remove, or modify the advice for an aspect, and change which point-cuts into which the advice is injected. Dynamic Weaving is far more flexible than Static Weaving, however due to the additional layers of indirection there is often a significant performance degradation for Dynamic Weaving over Static Weaving. As a result, many weavers prefer to use Static Weaving, but to delay weaving until the last possible opportunity to allow for greater flexibility. Bytecode weaving typically occurs at one or more of four points in the application lifecycle: 1. Application compilation/packaging known as Compile-time Weaving Copyright IBM 2010

68 2. Application deployment known as Deploy-time Weaving 3. Application class load time known as Load-time Weaving 4. In a running application known as Runtime Weaving RFC 159 Bytecode Weaving Page 5 of 42 Final November 8, 2010 The first opportunity is simply to apply the bytecode transformation as the code is compiled or packaged into an installation artefact. This type of weaving is useful for fixed aspects that are not implementation specific, however it is inflexible and difficult to customise. The second opportunity comes at application deployment time. This is more flexible than compilation time because it allows the deployment runtime to choose specific implementations, however it is still not able to respond to post deployment changes nor can the deployed code be easily reconfigured without completely re-deploying the application. The third opportunity for weaving is on a just in time basis, immediately before the class bytes are loaded by a ClassLoader. By waiting until this point the runtime can flexibly apply transforms based on the latest configuration and runtime state. This makes load time weaving a very flexible and popular weaving approach. Further flexibility can be achieved by weaving code into a running application, re-defining classes that have already been loaded. This is called Runtime Weaving, and allows for a static weaving strategy to be applied with a similar level of flexibility and control to a Dynamic Weaving strategy. Runtime Weaving is however less popular than Load-time Weaving as not all transformations can be applied at runtime, it is also highly invasive and, if regularly used, reduces the level of optimisation that can be applied to classes. Together bytecode weaving and AOP offer a powerful and widely used mechanism for implementing and extending POJO based application models with container-like services, however, in order to be applied at loadtime or runtime, they require a deep level of integration with the underlying runtime framework. Not only does Load-time Weaving require hooks in the application ClassLoader, but it may also introduce additional runtime dependencies that were not originally required to be present on the application classpath. In an OSGi framework this causes a number of problems. Firstly, a core architectural concept in OSGi is that class loading is abstracted by the Bundle interface. This abstraction provides no opportunity for bytecode weaving to occur as there is no way to hook in and replace the class bytes that are about to be defined. Secondly, the OSGi framework defines a very strict dependency graph between bundles. This means that any new dependencies added by the weaving process are unlikely to be visible to the bundle's classloader, even if they are present in the framework. It should be noted that compile-time and deploy-time weaving are both relatively easy to achieve in an existing OSGi framework. Compile-time weaving simply requires that any added dependencies are included in the bundle manifest when it is packaged, and can easily be determined by an analysis tool such as BND. Deploy-time weaving can be achieved through the use of a custom URL scheme when installing a bundle into the OSGi framework. This approach allows the URL handler to replace the contents of the bundle before it is installed, at which point classes can be woven and the bundle manifest updated as necessary. The core support for bytecode weaving in Java TM allows for both load-time and runtime weaving, but it also includes some optimisations for classes that need to be redefined. ClassFileTransformers can be registered as retransformation capable. Class retransformation is a special case of class redefinition where only retransformation capable weavers are called, in this case the non retransformation capable weavers are not called and the result from their previous transformation is used as the input to the retransformation capable transformers. The primary aim of this RFP is to provide standard mechanisms to address the difficulties associated with Loadtime and Runtime bytecode weaving in an OSGi framework. Copyright IBM 2010

69 RFC 159 Bytecode Weaving Page 6 of 42 Final November 8, Application Domain There are many different reasons that an application may require bytecode weaving. Some frameworks; for example JPA providers, EJB containers and Servlet Containers; may require that the classes they manage are woven before they can be used. This is typically expected by the application developer in advance of deployment, but should not require the developer to add any additional code or metadata, above that required by the relevant standard, to make it work. This is particularly important, because it is unlikely that all implementations of the containers will require weaving. This implementation decision should be transparent to the application developer. Other applications may have optional weaving dependencies, for example adding automatic transaction management if it is available in the runtime. This is also typically expected in advance by the application developer, but may also be added later by another developer re-packaging the application. Some application code may need to be woven without the developer ever knowing that the code would be woven. A good example of this is adding dynamic performance monitoring and load management, or adding method level debug trace using a proprietary tracing framework. These types of weaving are typically added by an application management system, and are initiated by an administrator with no access to the code or packaging of the application. 2.1 Terminology + Abbreviations AOP[3]. Aspect Advice Point-cut Byte-code Weaving Static Aspect Oriented Programming, a type of programming where cross-cutting concerns are identified and a piece of code (advice) is inserted into the normal application flow to address this concern. A cross-cutting concern within an application that is distinct from the main concern of individual modules. A good example is logging debug or audit information, which is important, but not the main concern of a business method in a payroll system. A piece of code or set of instructions that should be woven into a class file to address the concerns of an aspect. Advice may add additional instructions, methods or fields for use by a third party framework. A point-cut is an identified location at which advice should be injected to address the concern of an aspect. Point-cuts may be identified by many criteria, including annotations, method name matching and sets of bytecode instructions (e.g. the start of a catch block). The act of transforming compiled class files by inserting advice into one or more point-cuts identified in the classes. Bytecode weaving is a key tool in Aspect Oriented Programming (AOP). The act of weaving additional statements or blocks directly into compiled code without additional Copyright IBM 2010

70 RFC 159 Bytecode Weaving Page 7 of 42 Final November 8, 2010 Weaving Dynamic Weaving Compiletime Weaving Deploytime Weaving Load-time Weaving Runtime Weaving abstraction. Once woven, static aspects cannot typically be replaced. The act of weaving abstracted code blocks into class files, as a result aspects can be added, removed or modified dynamically while the classes are running The act of applying bytecode transformations at or immediately after the compilation/packaging of the class files. The act of applying bytecode transformations as the packaged artefacts are deployed into a framework or container. Similar to EJB deployment in a JEE application server. The act of applying transformations to class bytecode immediately before it is defined by a ClassLoader The act of applying transformations to class bytecode that has already been defined by a ClassLoader, forcing it to be dynamically redefined by the virtual machine. 3 Problem Description The OSGi Alliance core specification defines a set of strict modularity rules for reusable code modules called bundles. The specification also defines a class loading model to support the modularity rules which differs significantly from the standard class loading model used in a flat structure. Further to this class loading model the specification also defines an abstraction to the ClassLoader API. As previously discussed, there are a number of valuable use cases that can be elegantly solved using AOP and load-time weaving. There are also some enterprise technologies that are predicated on load-time weaving being available as a first class implementation mechanism. Bytecode weaving requires tight integration with the ClassLoader for the class to be woven, and also can alter the class dependency graph. Due to the restrictions and abstractions built in to the framework both of these requirements cause significant difficulties inside an OSGi framework. This RFC aims to add standard SPIs for bytecode weaving to the OSGi framework so that it is not necessary to violate the existing rules of the framework. 4 Requirements 1. It MUST be possible to register a bytecode transformer with a bundle so that the class bytecode can be transformed before it is loaded by the bundle classloader Copyright IBM 2010

71 RFC 159 Bytecode Weaving Page 8 of 42 Final November 8, It MUST be possible to register a bytecode transformer with a bundle before any classes have been loaded by the bundle classloader 3. It MUST be possible to dynamically register additional dependencies for a bundle that is going to have one or more class bytecodes transformed before any new classes are loaded 4. The solution MUST support both Static and Dynamic Weaving strategies. 5. A bundle MUST NOT require any special metadata for it to have its classes woven. 6. A solution SHOULD use the existing Java TM bytecode transformation APIs where possible[4]. 7. It SHOULD be possible to support more than one bytecode transformer per bundle 8. If more than one bytecode transformer is registered for a bundle it MUST be possible to define the order in which they are invoked, but this ordering SHOULD NOT violate any existing rules defined by the Java TM API. 9. It MAY be possible to register a bytecode transformer for an active bundle and programmatically trigger class redefinition so that runtime weaving can be performed 10. It MAY be possible to indicate that a bytecode transformer is retransformation capable when it is registered and programmatically trigger class retransformation. 5 Technical Solution 5.1 The Weaving Service This RFC proposes a new whiteboard model through which weavers can be registered with an OSGi framework. These services can then be used by the frameworks to allow the contents of a particular bundle to be woven Basic load-time weaving support In Java SE 5.0, some standard interfaces were introduced to support the Java Programming Language Instrumentation Services JSR. These were added to allow classes to be post-processed by the runtime before they are loaded into the VM by a ClassLoader. The core support for load-time weaving is based around the java.lang.instrument.classfiletransformer interface. This defines a single method which passes the raw bytecode for a Class along with other useful information such as the Class's name, ProtectionDomain, and the ClassLoader instance that is about to define the Class. This interface can be used by customised ClassLoaders to transform any bytes that they locate during findclass(). As such the most basic of loadtime weaving support can be added to a runtime using ClassFileTransformers and a mechanism for registering them with the runtime's ClassLoaders. A similar model should provide all the flexibility required for OSGi to perform load-time weaving, however a new interface will be required for two reasons. Firstly the core OSGi framework may run on Java SE environments Copyright IBM 2010

72 RFC 159 Bytecode Weaving Page 9 of 42 Final November 8, 2010 prior to 5.0. Secondly, the ClassFileTransformer does not provide any mechanism to introspect the the class-space wiring of a bundle. A WeavingHook should, however have access to the name of the class being loaded, the classloader defining it, the ProtectionDomain it is being defined in and the source class bytes to be defined. To add load-time weaving support within a framework, a bundle should register a service that implements the org.osgi.framework.weaving.weavinghook interface. This service will then be called by the framework whenever a Class is loaded. The Framework should not hold any locks when calling out to the WeavingHook services, and WeavingHook implementations must be thread-safe. Furthermore WeavingHook services may be re-entrant, and should be careful to avoid cycles when weaving, for example when a class is being woven the WeavingHook may implicitly or explicitly load a class. This second class load will also pass through the WeavingHook service, so care must be taken to avoid infinite looping. When calling a WeavingHook the framework provides a WovenClass implementation. The WovenClass represents a class being woven and allows for possible modification before a class is defined. A WovenClass provides read only access to the class name and ProtectionDomain. The WovenClass also provides access to an up-to-date copy of the class bytes, and a way to provide new, transformed bytes. The WovenClass also provides access to the BundleWiring associated with the bundle class loader which will define the class and access to a list of dynamic import package statements which can be used to add new dynamic import specifications to the bundle's class loader. If multiple WeavingHooks are registered in the service registry then they should be run, using the same input, in the order in which the service registry returns them, i.e. highest ranking and lowest service id first. Once the framework has called every WeavingHook for a given class, the WovenClass must be marked as complete indicating that no more modifications can be made to it in this definition. The WovenClass must still allow read access, but should prevent changes to its internal state either through unmodifiable collections, or through throwing IllegalStateException Error Handling Weaving hooks are very low level and extreme care must be taken by the weaving hook implementations to not disrupt normal class loading. In case a weaving hook throws an unexpected exception the framework must do the following: 1. If the exception is a WeavingException the framework must proceed to step If the exception is not a WeavingException the framework must blacklist the weaving hook registration and never call that weaving hook again for the lifetime of the weaving hook registration. 3. A framework event of type ERROR should be published which includes the exception thrown by the weaving hook. 4. All remaining weaving hook registrations must be skipped for the WovenClass and the WovenClass must be marked as complete. 5. The bundle class loader must throw a ClassFormatException with the cause being the exception thrown by the weaving hook. When a blacklisted weaving hook is unregistered it is removed from the blacklist. If that same weaving hook is registered again with a new service registration it will be called for new class loads. Copyright IBM 2010

73 5.1.3 More advanced load-time weaving support RFC 159 Bytecode Weaving Page 10 of 42 Final November 8, 2010 When modifying classes using a WeavingHook at load time it is possible to completely re-write the class bytecode. Method bodies and signatures may be modified; fields and methods may be added to, or removed from, the class; even the type hierarchy may be changed. In a standard Java environment this does not usually cause a significant problem, as any new dependencies that are added can be loaded as long as they are on the classpath somewhere. In OSGi, this is a more significant issue. As a result it is also crucially important for a WeavingHook service to allow a weaving client to add new dependencies to a bundle. The WovenClass provides a List<String> which contains dynamic import package specifications as defined by the DynamicImport-Package header. A weaving hook may add new dynamic import package specifications to this list. This makes it possible to wire a bundle to a package in the runtime that it did not declare a dependency on in its manifest. If the bundle must be wired to a particular exporter, then the bundle-symbolicname and bundle-version attributes may be used along with any other matching attributes. Wild cards are also allowed in the package name as supported by the DynamicImport-Package header. To allow a weaving hook to introspect the bundle wirings, and to tell the framework that a new package must be added, a WovenClass object must provide the BundleWiring associated with the bundle class loader defining the class. A BundleWiring can also be used to obtain the bundle's ClassLoader, it is not necessary to also pass a ClassLoader to the WeavingHook. If the WeavingHook wishes to modify the class bytecode then it should update the bytes in the WovenClass object. If no changes need to be made to the class bytecode then the WeavingHook should return without modifying the WovenClass. It is an error to attempt to add a null byte array to a WovenClass, and a NullPointerException should be thrown. If no new packages need to be dynamically imported by the bundle as a result of the weaving then no changes need to be made to the list of dynamic import package specifications. If as a result of the weaving new packages need to be added, or previously added dynamic imports are no longer needed, then the WeavingHook should modify the collection of dynamic imports appropriately. When dynamic import strings are added to the collection, the framework should validate that the strings are well formed and can be parsed. If validation fails the framework should throw an IllegalArgumentException. No wiring should be created by the framework at this stage The Weaving Processing The following steps must be followed by the bundle class loader when defining a new class. 1. A new WovenClass object is created with the class name and class bytes for the class being defined, and the bundle wiring and protection domain being used to define the class. 2. Each registered weaving hook is called with the woven class object. If any exception is thrown by a weaving hook then class definition fails as described in a previous section and the weaving process is terminated. 3. The current snapshot of the woven class's dynamic import package statements are appended to the current list of dynamic import packages for the bundle class loader. No wires are established at this time. Dynamic wires are established only through normal class loading delegation like normal dynamic import packages for a bundle. The bundle class loader should avoid appending the same dynamic import statement over and over, causing the list to grow indefinitely. 4. The current snapshot of the woven class's bytecode is used to define the class. If class definition succeeds then the woven class is given a reference to the new Class object. The woven class is marked as complete even if class definition fails. Copyright IBM 2010

74 5.2 Weaving Service Javadoc OSGi Javadoc 10/8/10 5:46 PM Package Summary org.osgi.frame work.hooks.we aving RFC 159 Bytecode Weaving Page 11 of 42 Final November 8, 2010 Framework Weaving Hooks Package Version Page Copyright IBM 2010

75 Package org.osgi.framework.hooks.weaving Package org.osgi.framework.hooks.weaving Framework Weaving Hooks Package Version 1.0. See: Description Interface Summary WeavingHook OSGi Framework Weaving Hook Service. 14 WovenClass A class being woven. 15 Page Exception Summary WeavingExcep tion A weaving exception used to indicate that the class load should be failed but the weaving hook must not be blacklisted by the framework. Page 13 Package org.osgi.framework.hooks.weaving Description Framework Weaving Hooks Package Version 1.0. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. Example import for consumers using the API in this package: Import-Package: org.osgi.framework.hooks.weaving; version="[1.0,2.0)" OSGi Javadoc -- 10/8/10 Page 12 of 42

76 Package org.osgi.service.weaving Class WeavingException org.osgi.framework.hooks.weaving java.lang.object java.lang.throwable java.lang.exception All Implemented Interfaces: Serializable java.lang.runtimeexception org.osgi.framework.hooks.weaving.weavingexception public class WeavingException extends RuntimeException A weaving exception used to indicate that the class load should be failed but the weaving hook must not be blacklisted by the framework. This exception conforms to the general purpose exception chaining mechanism. Version: $Id: eb38b85f6ed66ec445fb2f0ee7143df021327a9a $ Constructor Summary WeavingException(String msg) Creates a WeavingException with the specified message. WeavingException(String msg, Throwable cause) Creates a WeavingException with the specified message and exception cause. Pag e Constructor Detail WeavingException public WeavingException(String msg, Throwable cause) Creates a WeavingException with the specified message and exception cause. Parameters: msg - The associated message. cause - The cause of this exception. WeavingException public WeavingException(String msg) Creates a WeavingException with the specified message. Parameters: msg - The message. OSGi Javadoc -- 06/09/10 Page 13 of 42

77 Interface WeavingService Interface WeavingHook org.osgi.framework.hooks.weaving public interface WeavingHook OSGi Framework Weaving Hook Service. Bundles registering this service will be called during framework class loading operations. Weaving hook services are called when a class is being loaded by the framework and have an opportunity to transform the class file bytes that represents the class being loaded. Weaving hooks may also ask the framework to wire in additional dynamic imports to the bundle. When a class is being loaded, the framework will create a WovenClass object for the class and pass it to each registered weaving hook service for possible modification. The first weaving hook called will see the original class file bytes. Subsequently called weaving hooks will see the class file bytes as modified by previously called weaving hooks. Version: $Id: d baba2db1c56aab1e06ee953fd6365 $ ThreadSafe Method Summary void weave(wovenclass wovenclass) Weaving hook method. Pag e 14 Method Detail weave void weave(wovenclass wovenclass) Weaving hook method. This method can modify the specified woven class object to weave the class being defined. If this method throws any exception, the framework must log the exception and fail the class load in progress. This weaving hook service must be blacklisted by the framework and must not be called again. The blacklisting of this weaving hook service must expire when this weaving hook service is unregistered. However, this method can throw a WeavingException to deliberately fail the class load in progress without being blacklisted by the framework. Parameters: wovenclass - The WovenClass object that represents the data that will be used to define the class. Throws: WeavingException - If this weaving hook wants to deliberately fail the class load in progress without being blacklisted by the framework OSGi Javadoc -- 06/09/10 Page 14 of 42

78 Interface RetransformingWeaver Interface WovenClass org.osgi.framework.hooks.weaving public interface WovenClass A class being woven. This object represents a class being woven and is passed to each WeavingHook for possible modification. It allows access to the most recently transformed class file bytes and to any additional packages that should be added to the bundle as dynamic imports. After weaving is complete, this object becomes effectively immutable. Version: $Id: f bd0632e85242cac434a6bb8a759dff6 $ NotThreadSafe Method Summary org.osgi.f ramework.w iring.bund lewiring byte[] String Class<?> getbundlewiring() Returns the bundle wiring whose class loader will define the woven class. 17 getbytes() Returns the class file bytes to be used to define the named class. getclassname() Returns the fully qualified name of the class being woven. getdefinedclass() Returns the class associated with this woven class. List<Strin g> getdynamicimports() Returns the list of dynamic import package descriptions to add to the bundle wiring for this woven class. Protection Domain boolean void getprotectiondomain() Returns the protection domain to which the woven class will be assigned when it is defined. isweavingcomplete() Returns whether weaving is complete in this woven class. setbytes(byte[] newbytes) Set the class file bytes to be used to define the named class. Pag e Method Detail getbytes byte[] getbytes() Returns the class file bytes to be used to define the named class. While weaving is not complete, this method returns a reference to the class files byte array contained in this object. After weaving is complete, this object becomes effectively immutable and a copy of the class file byte array is returned. Returns: The bytes to be used to define the named class. OSGi Javadoc -- 09/09/10 Page 15 of 42

79 Interface RetransformingWeaver setbytes void setbytes(byte[] newbytes) Set the class file bytes to be used to define the named class. This method must not be called outside invocations of the weave method by the framework. While weaving is not complete, this method replaces the reference to the array contained in this object with the specified array. After weaving is complete, this object becomes effectively immutable and this method will throw an IllegalStateException. Parameters: newbytes - The new classfile that will be used to define the named class. The specified array is retained by this object and the caller must not modify the specified array. Throws: NullPointerException - If newbytes is null. IllegalStateException - If weaving is complete. getdynamicimports List<String> getdynamicimports() Returns the list of dynamic import package descriptions to add to the bundle wiring for this woven class. Changes made to the returned list will be visible to later weaving hooks called with this object. The returned list must not be modified outside invocations of the weave method by the framework. After weaving is complete, this object becomes effectively immutable and the returned list will be unmodifiable. Returns: A list containing zero or more dynamic import package descriptions to add to the bundle wiring for this woven class. This list must throw IllegalArgumentException if a malformed dynamic import package description is added. See Also: "Core Specification, Dynamic Import Package, for the syntax of a dynamic import package description." isweavingcomplete boolean isweavingcomplete() Returns whether weaving is complete in this woven class. Weaving is complete after the last weaving hook is called and the class is defined. After weaving is complete, this object becomes effectively immutable. Returns: true weaving is complete, false otherwise. getclassname String getclassname() Returns the fully qualified name of the class being woven. Returns: The fully qualified name of the class being woven. OSGi Javadoc -- 09/09/10 Page 16 of 42

80 Interface RetransformingWeaver getprotectiondomain ProtectionDomain getprotectiondomain() Returns the protection domain to which the woven class will be assigned when it is defined. Returns: The protection domain to which the woven class will be assigned when it is defined, or null if no protection domain will be assigned. getdefinedclass Class<?> getdefinedclass() Returns the class associated with this woven class. When loading a class for the first time this method will return null until weaving is complete. Once weaving is complete, this method will return the class object. Returns: The class associated with this woven class, or null if weaving is not complete or the class definition failed. getbundlewiring org.osgi.framework.wiring.bundlewiring getbundlewiring() Returns the bundle wiring whose class loader will define the woven class. Returns: The bundle wiring whose class loader will define the woven class. Java API documentation generated with DocFlex/Doclet v1.5.6 DocFlex/Doclet is both a multi-format Javadoc doclet and a free edition of DocFlex/Javadoc. If you need to customize your Javadoc without writing a full-blown doclet from scratch, DocFlex/Javadoc may be the only tool able to help you! Find out more at 6 Command Line API This specification would not benefit from a command line API OSGi Javadoc -- 09/09/10 Page 17 of 42

81 Interface RetransformingWeaver 7 JMX API This API does not provide function suitable for exposing via JMX 8 Considered Alternatives After the Ottawa F2F the following two approaches were rejected in favour of a Weaving Service approach. 8.1 Bundle re-writing In this embodiment the weavers either detect the installation/resolution of the bundle that they wish to weave, or register a URLHandler that can be used to intercept bundle installation before the bundles reach the framework. The contents of the bundle are scanned by the weaver, and a new bundle Jar is generated, including the woven code. This generated Jar is then installed into the framework in place of the original, or potentially as an update, and the woven code will be loaded automatically. Any additional dependencies can be added to the bundle manifest when the bundle is being rewritten. The benefits of this solution are that it is simpler for the framework to implement, however there are a number of drawbacks. The weaving available via this mechanism is effectively deploy-time rather than load time weaving, and many decisions will have to be made without knowing if or when a class will be loaded. Further to this it adds a significant churn to the framework, with many bundle restarts/updates/installations. It is also not possible to guarantee whether the woven bundle will resolve to the same class space as the original, which may violate a number of weaving assumptions. There are also significant potential issues around supporting multiple weavers in this scenario, as there can only be one URLHandler, and there is potentially a lot of redundant processing 8.2 Woven Fragments In this embodiment a bundle must know that it will be woven, and therefore be packaged as a bundle fragment. This fragment will be unable to resolve until such time as a suitable host bundle is available in the framework. The weaving bundle can then generate and install a host bundle containing the woven classes. These woven classes will be at the front of the classpath, and be used in preference to the originals from the fragment. This approach shares some benefits and drawbacks with Bundle re-writing. It is simple for the framework to implement, but the weaving available via this mechanism is effectively deploy-time rather than load time weaving. It is also not possible to know what class space the bundle will resolve to ahead of time, nor is is possible to guarantee that the fragment will attach (due to incompatible additional pacakges added during weaving). This means that woven fragments can be quite fragile.woven fragments also require the woven bundle to know ahead of time that it will be woven, which violates requirement 5. As for other strategies, some level of coordination is needed to support multiple weavers when generating the host bundle. It should also be noted that any bundles that need to have a bundle activator cannot support this mechanism, as it is forbidden for a fragment to have a Bundle- Activator header. Numerous other headers may also cause issues if not correctly migrated to the host bundle. The following implementation was considered for the weaving service. OSGi Javadoc -- 09/09/10 Page 18 of 42

82 Interface RetransformingWeaver 8.3 The Weaving Service This RFC proposes a new interface to which a Bundle can be adapted. This interface can then be used by weaving bundles to weave the contents of a particular bundle. The weaving service aims to support the major functionality required to weave, or re-weave classes within a bundle. This includes the ability to register a bytecode transformer for use when the bundle loads classes and to add additional package dependencies. Furthermore this interface will enable more advanced concepts, such as class redefinition, or runtime retransformation of classes Load-time weaving support Basic load-time weaving support In Java SE 5.0, some standard interfaces were introduced to support the Java Programming Language Instrumentation Services JSR. These were added to allow classes to be post-processed by the runtime before they are loaded into the VM by a ClassLoader. The core support for load-time weaving is based around the java.lang.instrument.classfiletransformer interface. This defines a single method which passes the raw bytecode for a Class along with other useful information such as the Class's name, ProtectionDomain, and the ClassLoader instance that is about to define the Class. This interface can be used by customised ClassLoaders to transform any bytes that they locate during findclass(). As such the most basic of load-time weaving support can be added to a runtime using ClassFileTransformers and a mechanism for registering them with the runtime's ClassLoaders. This model should provide all the flexibility required for OSGi to include a load-time weaving service for a bundle, however, the core OSGi framework may run on Java SE environments prior to 5.0. Therefore the weaving service should only be available within an OSGi framework if it is running on Java SE 5.0 or higher. To provide basic load-time weaving support, the weaving service should offer methods to register and de-register java.lang.instrument.classfiletransformer instances against a bundle. Obviously this is only possible when the bundle is in a state where it has a ClassLoader (i.e. RESOLVED, STARTING, ACTIVE and STOPPING), and an IllegalStateException should be thrown otherwise. If a bundle later returns to an unresolved state and has its classloader discarded then any registered ClassFileTransformers should also be discarded. If a ClassTransformer needs to know which bundle a class is defined in (for example if the same transformer instance is registered against more than one bundle) then the ClassLoader should be cast to BundleReference, and the defining bundle can be retrieved from there. ClassTransformers must be thread-safe, and should expect to receive multiple concurrent calls, even if the transformer is only registered with a single bundle. If multiple ClassFileTransformers are registered against a bundle then, when a new class is being loaded, they should be run in the order in which they were registered More advanced load-time weaving support When modifying classes using a ClassFileTransformer at load time it is possible to completely re-write the class bytecode. Method bodies and signatures may be modified; fields and methods may be added to, or removed from, the class; even the type hierarchy may be changed. In a standard Java environment this does not usually cause a significant problem, as any new dependencies that are added can be loaded as long as they are on the classpath somewhere. In OSGi, this is a more significant issue. As a result it is also crucially important for the weaving service to allow a weaving client to add new dependencies to a bundle. This support must make it possible to wire a bundle to a particular package in the runtime, rather than adding a new import specification for the framework to resolve. This allows a transformer to guarantee a particular classspace, rather than hoping that the framework resolves to the intended result. As when adding a transformer, this mechanism should throw an IllegalStateException if the bundle does not have a defined ClassLoader. Furthermore, if the package cannot be added to the bundle because it would create an invalid class-space, then a BundleException should be thrown. In the case where the bundle already imports the package from the requested source then the method should exit normally. OSGi Javadoc -- 09/09/10 Page 19 of 42

83 Interface RetransformingWeaver Class redefinition support In Java 5.0, the Java Programming Language Instrumentation Services JSR defined an integration point between Java code running on the Virtual Machine and the underlying Virtual Machine runtime. This integration point is the Instrumentation interface, which is obtained through the use of a JavaAgent. In Java SE 6.0 more access points were introduced to allow Java applications to use the Instrumentation interface without having to use a JavaAgent. The Instrumentation interface provides a mechanism by which classes can be re-defined within a running system. Class redefinition is used to replace the currently running version of a class with a new version of the class bytecode. A good example would be a debugging program that replaces a defective method implementation in a running system by supplying newly compiled bytes for the class. As more programs take advantage of the runtime compilation support that has been added to Java, the number of use cases for this function will continue to grow. The weaving service should optionally offer the ability to redefine classes within a bundle if support is available in the underlying runtime. This support may be unavailable either because: The framework implementation does not implement support class redefinition The underlying Virtual Machine does not support class redefinition The particular class is not suitable for redefinition (for example because it is a protected Java class like java.lang.string) The weaving service should offer a method that can be used to determine whether class redefinition support is available in the runtime, similar support is already available on the Instrumentation interface for determining the underlying VM's support. The weaving service should also supply a utility method such that clients can determine whether a particular class may be redefined. This utility method should take account of the bundle that defined the class, a class may be modifiable, however it cannot be re-defined by a bundle other than the one that originally defined it. To perform Class redefinition the Weaving service should offer a method through which a client can indicate a set of classes that should be transformed. The java.lang.instrument.classdefinition bean allows clients to supply a Class, and a new set of bytecode that should be used to redefine it. This method should throw UnmodifiableClassException if any of the supplied ClassDefinitions refer to classes that may not be modified by this bundle. The method should also throw UnsupportedOperationException if redefinition is not supported in this framework instance (whether this is a framework or VM restriction). Any LinkageError, VerifyError or other error that occurs during the redefinition should be thrown back to the client. Once a class has been redefined, any existing stack frames using the class's methods will continue using the old bytecode until such time as they no longer have stack frames that use the old class definition. All other invocations will begin using the new bytecode immediately. No static initialisers will be re-run, and any static fields will retain their previous state. Instances will be similarly unaffected Limitations of Class redefinition The Java specification places strong restrictions on the changes that can be made through class redefinition. Before a class has been defined it can be changed in drastic ways by a transformer, however once the class has been defined the transformations possible via redefinition are limited. It is possible to change method implementations, constant pool entries and attributes. It is not possible to add, remove or modify methods or fields, or to change the inheritance hierarchy of the class. If such a change is attempted there will be an Error when attempting to redefine the class and the class will not be changed. To effect a change that cannot be made within these limitations it is necessary to shutdown and reresolve the bundle, registering a load-time transformer to make the changes before the class is first defined Interactions with weaving As mentioned above, there are strong limitations on the allowable changes that can be made via class redefinition. If a class being redefined had originally been transformed as it was loaded, it is important that it is transformed again as it is being redefined. If the transformers are not run again, then any methods/fields that were changed, or any hierarchy changes that were made, will not be present in the bytecode for redefinition. Therefore any transformations should be run again, using the new class bytecode as the initial input to the transformation chain. OSGi Javadoc -- 09/09/10 Page 20 of 42

84 Interface RetransformingWeaver It is possible that the overall result of the transformation chain will not satisfy the allowed rules for redefined bytecode. This may occur if new transformers have been added or old transformers have been removed. In this case the redefinition will fail in the same way as if the originally supplied redefinition bytecode made illegal changes, and an Error will be propagated to the client Runtime retransformation support In Java 6.0 changes were made to the Java Programming Language Instrumentation Services API to allow for classes to be retransformed. Retransformation is similar to redefinition, except that it does not allow for the provision of new Class bytecode as a start point. Retransformation effectively reloads the class bytes from whatever source they were originally retrieved, and re-applies bytecode transformations to the class, before updating the class definition in the virtual machine. Retransformation has two main advantages over redefinition The client does not need to know the orginal bytes that were used to define the class to perform a retransformation Retransformation allows for an additional level of optimisation and safety Retransformation capable and incapable transformers As for redefinition, retransformation allows the same, much more limited, set of transformations to be made rather than the free reign transformers have prior to the initial definition of the class. In order to allow for this transformers must opt in to being retransformation capable. By doing this the transformer guarantees that it does not make changes to the class that violate the retransformation restrictions. This can be achieved by adding the transformer with a boolean flag indicating whether the transformer is retransformation capable or not. In order to cope with non retransformation capable transformers, the transformations must be applied in a particular order. This order is as follows: The retransformation incapable transformers, in the order in which they were registered. The retransformation capable transformers, in the order in which they were registerered This ordering allows for the results of the retransformation incapable transformer chain to be cached for future retransformations. This should then be provided as input to the retransformation capable chain. This caching both improves performance, but also limits the risk that an incompatible change will be made to the bytecode by only calling transformers that have agreed to the restrictions required by retransformation. To ensure consistency, this transformation order should be used in all transformations. Whether at first class-load, redefinition or retransformation. 8.4 Weaving Service Javadoc OSGi Javadoc -- 09/09/10 Page 21 of 42

85 RFC 159 Bytecode Weaving Page 22 of 42 Final November 8, 2010 OSGi Javadoc 06/09/10 13:03 Package Summary org.osgi.servic e.weaving Page 12 Copyright IBM 2010

86 Package org.osgi.service.weaving Package org.osgi.service.weaving Interface Summary WeavingServic e The WeavingService allows a client to perform weaving tasks for the host bundle. 17 Page OSGi Javadoc -- 06/09/10 Page 23 of 42

87 Interface WeavingService Interface WeavingService org.osgi.service.weaving public interface WeavingService The WeavingService allows a client to perform weaving tasks for the host bundle. Method Summary void void Class<?>[] org.osgi.f ramework.b undle boolean boolean boolean void void boolean void addpackagetodependencies(org.osgi.service.packageadmin.exportedpackage pkg) Adds a specific package to the imports of this Bundle addtransformer(classfiletransformer transformer, boolean canretransform) Adds a ClassFileTransformer that will be called for any classes subsequently loaded or redefined by this bundle. getallbundleloadedclasses() A method to query the list of classes that have been loaded by this bundle getbundle() Get the parent bundle for this WeavingService ismodifiableclass(class<?> theclass) Used to find out whether the supplied class can be modified through redefinition or retransformation by this bundle isredefinitionsupported() Used to determine whether the framework currently supports class redefinition. isretransformationsupported() Used to determine whether the framework currently supports retransformation. redefineclasses(classdefinition... classes) Redefine the supplied classes using the new bytes provided. removepackagefromdependencies(org.osgi.service.packageadmin.exportedpackage pkg) Removes a specific package from the imports of this bundle. removetransformer(classfiletransformer transformer) Remove a previously added transformer from the list of transformers. retransformclasses(class<?>... classes) Retransform the supplied classes using the most recently defined source bytes. Pag e Method Detail addtransformer void addtransformer(classfiletransformer transformer, boolean canretransform) throws IllegalStateException, SecurityException Adds a ClassFileTransformer that will be called for any classes subsequently loaded or redefined by this bundle. If canretransform is true then the transformer will also be called for any classes being retransformed.note that as defined by java.lang.instrument.instrumentation... redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions. The class file bytes are not checked, verified and installed until after the transformations have been applied, if the resultant bytes are in error this method will throw an exception. The ClassFileTransformer added will be inserted in a list structure which determines the order in which transformers are called. The lists of retransformation capable and incapable transformers are separate, and the incapable transformers are called first. OSGi Javadoc -- 06/09/10 Page 24 of 42

88 Interface WeavingService Throws: IllegalStateException - If the bundle is not in an appropriate state (RESOLVED, STARTING, ACTIVE, STOPPING) SecurityException - if the caller does not have sufficient privilege to add a transformer to this bundle NullPointerException - if the transformer is null addpackagetodependencies void addpackagetodependencies(org.osgi.service.packageadmin.exportedpackage pkg) throws org.osgi.framework.bundleexception, IllegalStateException, SecurityException Adds a specific package to the imports of this Bundle Parameters: pkg - The org.osgi.service.packageadmin.exportedpackage that must be wired. Throws: org.osgi.framework.bundleexception - If wiring to this package is not possible. This may be because it would lead to an inconsistent class space or some other reason. IllegalStateException - If the bundle is not in an appropriate state (RESOLVED, STARTING, ACTIVE, STOPPING) SecurityException - if the caller does not have sufficient privilege to add a package dependency to this bundle NullPointerException - if the package is null removepackagefromdependencies void removepackagefromdependencies(org.osgi.service.packageadmin.exportedpackage pkg) throws org.osgi.framework.bundleexception, IllegalArgumentException, IllegalStateException, SecurityException Removes a specific package from the imports of this bundle. Note that when re-transformation is supported it is not safe for a non re-transformation capable transformer to remove any added packages. Subsequent re-transformations will reuse the results from previous transformations using the non re-transformation capable weavers. This means that any added dependencies may be required, even after the original weaver has been removed. Throws: org.osgi.framework.bundleexception - If the package wiring cannot be removed from this bundle, either because it is defined in the bundle manifest, or for some other reason. IllegalArgumentException - If the package is not imported by this bundle IllegalStateException - If the bundle is not in an appropriate state (RESOLVED, STARTING, ACTIVE, STOPPING) SecurityException - if the caller does not have sufficient privilege to remove a package dependency from this bundle NullPointerException - if the package is null getallbundleloadedclasses Class<?>[] getallbundleloadedclasses() A method to query the list of classes that have been loaded by this bundle Returns: All the classes that have been loaded by this Bundle OSGi Javadoc -- 06/09/10 Page 25 of 42

89 Interface WeavingService ismodifiableclass boolean ismodifiableclass(class<?> theclass) Used to find out whether the supplied class can be modified through redefinition or retransformation by this bundle Parameters: theclass - The Class to check Returns: true if the class was loaded by this bundle and is allowed to be re-transformed, false otherwise Throws: NullPointerException - if the class is null isretransformationsupported boolean isretransformationsupported() Used to determine whether the framework currently supports retransformation. This may return false if the framework, or the VM, or both do not have the relevant support. Returns: true if class retransformation is supported in the current framework instance. isredefinitionsupported boolean isredefinitionsupported() Used to determine whether the framework currently supports class redefinition. This may return false if the framework, or the VM, or both do not have the relevant support. Returns: true if class redefinition is supported in the current framework instance. removetransformer boolean removetransformer(classfiletransformer transformer) throws SecurityException Remove a previously added transformer from the list of transformers. The first matching instance of the transformer in the list will be removed. Note that after removal the ClassFileTransformer may still be called for class transformations that were still in process. It will not be called for any new transformations that begin after it is removed. Returns: true if the ClassFileTransformer was found and removed, false otherwise Throws: SecurityException - if the caller does not have sufficient privilege to remove a ClassFileTransformer from this bundle NullPointerException - if the transformer is null OSGi Javadoc -- 06/09/10 Page 26 of 42

90 Interface WeavingService redefineclasses void redefineclasses(classdefinition... classes) throws UnmodifiableClassException, UnsupportedOperationException Redefine the supplied classes using the new bytes provided. This method follows the general contract for class re-definition in Java. The List of non retransformation capable transformers is called again, using the new bytes supplied in each ClassDefinition as a starting point. The retransformation capable transformers are then called again, in order, and the resulting bytes are used to replace the existing class. As per the Javadoc for java.lang.instrument.instrumentation: This method operates on a set in order to allow interdependent changes to more than one class at the same time (a redefinition of class A can require a redefinition of class B). If a redefined method has active stack frames, those active frames continue to run the bytecodes of the original method. The redefined method will be used on new invokes. This method does not cause any initialization except that which would occur under the customary JVM semantics. In other words, redefining a class does not cause its initializers to be run. The values of static variables will remain as they were prior to the call. If this method throws an exception, no classes have been redefined. Parameters: classes - The classes to re-define Throws: UnmodifiableClassException - If one or more of the {@linkclassredefinition} objects is not for a modifiable class in this bundle UnsupportedOperationException - If re-definition is not supported NullPointerException - if the array of class definitions is null retransformclasses void retransformclasses(class<?>... classes) throws UnmodifiableClassException, UnsupportedOperationException Retransform the supplied classes using the most recently defined source bytes. This method follows the general contract for class re-transformation in Java. The previous output from the List of non re-weaving capable transformers is used, no new non re-weaving capable weavers will be called, and the result will not change if previously used non re-weaving capable weavers have been removed. The re-weaving capable weavers are then called again, in order, and the resulting bytes are used to replace the existing class. As per the Javadoc for java.lang.instrument.instrumentation: This method operates on a set in order to allow interdependent changes to more than one class at the same time (a retransformation of class A can require a retransformation of class B). If a retransformed method has active stack frames, those active frames continue to run the bytecodes of the original method. The retransformed method will be used on new invokes. OSGi Javadoc -- 06/09/10 Page 27 of 42

91 Interface WeavingService This method does not cause any initialization except that which would occur under the customary JVM semantics. In other words, retransforming a class does not cause its initializers to be run. The values of static variables will remain as they were prior to the call. If this method throws an exception, no classes have been retransformed. Parameters: classes - The classes to retransform Throws: UnmodifiableClassException - If one or more of the classes supplied is not a modifiable by this bundle. UnsupportedOperationException - If re-weaving is not supported NullPointerException - if the array of classes is null getbundle org.osgi.framework.bundle getbundle() Get the parent bundle for this WeavingService Returns: the bundle that created this Weaving Service. Java API documentation generated with DocFlex/Doclet v1.5.6 DocFlex/Doclet is both a multi-format Javadoc doclet and a free edition of DocFlex/Javadoc. If you need to customize your Javadoc without writing a full-blown doclet from scratch, DocFlex/Javadoc may be the only tool able to help you! Find out more at A whiteboard model that included retransformation and redefinition was considered, but proved too large to design and specify all at once: Class redefinition support In Java 5.0, the Java Programming Language Instrumentation Services JSR defined an integration point between Java code running on the Virtual Machine and the underlying Virtual Machine runtime. This integration point is the Instrumentation interface, which is obtained through the use of a JavaAgent. In Java SE 6.0 more access points were introduced to allow Java applications to use the Instrumentation interface without having to use a JavaAgent. The Instrumentation interface provides a mechanism by which classes can be re-defined within a running system. Class redefinition is used to replace the currently running version of a class with a new version of the class bytecode. A good example would be a debugging program that replaces a defective method implementation in a running system by supplying newly compiled bytes for the class. As more programs take advantage of the runtime compilation support that has been added to Java, the number of use cases for this function will continue to grow. The framework should provide an org.osgi.framework.weaving.weavingadmin service that optionally offers the ability to redefine classes within a bundle if support is available in the underlying VM. This support may be unavailable either because: The framework implementation does not implement support class redefinition The underlying Virtual Machine does not support class redefinition The WeavingAdmin service should offer a method that can be used to determine whether class redefinition support is available in the runtime, similar support is already available on the Instrumentation interface for determining the underlying VM's support. The weaving service should also supply a utility method such that clients can determine whether a particular class may be redefined or retransformed. This utility method should take OSGi Javadoc -- 06/09/10 Page 28 of 42

92 Interface WeavingService account whether modification of the class is forbidden by the VM, but should also prevent redefinition of classes that were not loaded by a framework classloader (for example classes loaded by boot delegation). To perform Class redefinition the Weaving service should offer a method through which a client can indicate a set of classes that should be redefined. As the existing class java.lang.instrument.classdefinition is only available in Java 5, this RFC proposes a similar class called org.osgi.framework.weaving.classredefinition. This javabean allows clients to supply a Class, and a new set of bytecode that should be used to redefine that class. This method should throw IllegalArgumentException if any of the supplied ClassRedefinitions refer to classes that may not be modified. The method should also throw UnsupportedOperationException if redefinition is not supported in this framework instance (whether this is a framework or VM restriction). Any LinkageError, VerifyError or other Error that occurs during the redefinition should be thrown back to the client that initiated the redefinition. As per the behaviour of the Instrumentation interface, once a class has been redefined, any existing stack frames using the class's methods will continue using the old bytecode until such time as those stack frames complete. All other invocations will begin using the new bytecode immediately. No static initialisers will be re-run, and any static fields will retain their previous state. Instances will be similarly unaffected. If any exceptions occur when redefining a set of classes then none of the classes will have been modified. If a ClassRedefinition is constructed with null bytes or a null Class, then a NullPointerException will be thrown. Similarly if the ClassRedefinition arrray, or any of the entries in the array, is null then a NullPointerException will be thrown. To further support the redefinition of classes it should be possible to query the WeavingAdmin service to find out the classes that have been loaded by a bundle's ClassLoader. Weavers can make use of this function to determine whether redefinition is necessary to update running classes, or whether the update can be delegated to a load-time weaver Limitations of Class redefinition The Java specification places strong restrictions on the changes that can be made through class redefinition. Before a class has been defined it can be changed in drastic ways by a transformer, however once the class has been defined the transformations possible via redefinition are limited. It is possible to change method implementations, constant pool entries and attributes. It is not possible to add, remove or modify methods or fields, or to change the inheritance hierarchy of the class. If such a change is attempted there will be an Error issued by the Virtual Machine when attempting to redefine the class and the class will not be changed. To effect a change that cannot be made within these limitations it is necessary to shutdown and re-resolve the bundle, registering a load-time transformer to make the changes before the class is first defined Interactions with weaving As mentioned above, there are strong limitations on the allowable changes that can be made via class redefinition. If a class being redefined had originally been transformed as it was loaded, it is important that it is transformed again as it is being redefined. If the transformers are not run again, then any methods/fields that were changed, or any hierarchy changes that were made, will not be present in the bytecode for redefinition. Therefore when a class redefinition occurs any WeavingHook services in the service registry should be called to apply transformations to the redefined class bytes. The framework should use the new class bytecode as the initial input to the transformation chain. It is possible that the overall result of the transformation chain will not satisfy the allowed rules for redefined bytecode. This may occur if new transformers have been added or old transformers have been removed. In this case the redefinition will fail in the same way as if the originally supplied redefinition bytecode made illegal changes, and an Error will be propagated to the client. For the support of Class retransformation, the framework should cache the resulting byte array produced by the chain of WeavingHook services. This data should replace any previously cached class bytecode. OSGi Javadoc -- 06/09/10 Page 29 of 42

93 Interface WeavingService Runtime retransformation support In Java 6.0 changes were made to the Java Programming Language Instrumentation Services API to allow for classes to be retransformed. Retransformation is similar to redefinition, except that it does not allow for the provision of new Class bytecode as a start point. Retransformation effectively reloads the class bytes from whatever source they were originally retrieved, and re-applies bytecode transformations to the class, before updating the class definition in the virtual machine. Retransformation has two main advantages over redefinition The client does not need to know the orginal bytes that were used to define the class to perform a retransformation Retransformation allows for an additional level of optimisation and safety As for redefinition, the WeavingAdmin service should allow clients to query whether retransformation is supported. This support may be unavailable either because: The framework implementation does not implement support class retransformation The underlying Virtual Machine does not support class retransformation Retransformation capable and incapable transformers As for redefinition, retransformation allows the same, much more limited, set of transformations to be made rather than the free reign transformers have prior to the initial definition of the class. In order to allow for this transformers must opt in to being retransformation capable. By doing this the transformer guarantees that it does not make changes to the class that violate the retransformation restrictions. In OSGi, this means that retransformation capable weaving services should implement and register under the org.osgi.framework.retransformingweaver interface. This interface extends the WeavingHook, and has no additional methods, it merely serves as an additional marker to the framework. In order to allow retransformation to occur the WeavingHook and RetransformingWeaver services must be called in a particular order. This order is as follows: The WeavingHook services, in the order in which they are returned by the service registry. The RetransformingWeaver services, in the order in which they are returned by the service registry. This ordering should be applied for every class load and redefinition, meaning that both WeavingHook services and RetransformingWeaver services should be called. When a client requrests that the framework reweaves a class, the WeavingHook services should not be called again. Instead the framework should use the transformed byte array it cached from the most recent class definition or redefinition as input to the chain of RetransformingWeaver services. This caching both improves performance, but also limits the risk that an incompatible change will be made to the bytecode by only calling transformers that have agreed to the restrictions required by retransformation. As for Class redefinition, the WeavingAdmin service should throw any Errors back to the client that initiated the retransformation. These errors may be caused by invalid or illegal transformations, or for some other reason. The WeavingAdmin service should throw UnsupportedOperationException if retransformation is not supported by the framework. It should throw IllegalArgumentException if any of the supplied classes are not modifiable, or a NullPointerException if the array of classes, or any entry in the array, is null. As per the behaviour of the Instrumentation interface, once a class has been retransformed, any existing stack frames using the class's methods will continue using the old bytecode until such time as those stack frames complete. All other invocations will begin using the new bytecode immediately. No static initialisers will be re-run, and any static fields will retain their previous state. Instances will be similarly unaffected. If any exceptions occur when redefining a set of classes then none of the classes will have been modified. OSGi Javadoc -- 06/09/10 Page 30 of 42

94 Interface WeavingService 8.5 Weaving Service Javadoc OSGi Javadoc -- 06/09/10 Page 31 of 42

95 RFC 159 Bytecode Weaving Page 32 of 42 Final November 8, 2010 OSGi Javadoc 10/09/10 14:55 Package Summary org.osgi.frame work.weaving Page 12 Copyright IBM 2010

96 Package org.osgi.service.weaving Package org.osgi.framework.weaving Interface Summary Retransforming Weaver A RetransformingWeaver is a special type of WeavingHook that obeys the limitations required for runtime re-transformation of classes. WeavingAdmin The WeavingAdmin allows a client to perform weaving tasks for the host bundle. 17 WeavingHook This interface should be used to register weaving implementations within an OSGi framework Page Class Summary ClassRedefiniti on WovenClass This class is used to encapsulate a Class and new bytecode that should be used to redefine the Class This class represents the output of a WeavingHook. Page 13 Error: Refer ence sourc e not found OSGi Javadoc -- 06/09/10 Page 33 of 42

97 Interface WeavingService Class ClassRedefinition org.osgi.framework.weaving java.lang.object org.osgi.framework.weaving.classredefinition public class ClassRedefinition extends Object This class is used to encapsulate a Class and new bytecode that should be used to redefine the Class Constructor Summary ClassRedefinition(Class<?> classtoredefine, byte[] newclassbytes) Create a new ClassRedefinition for the supplied Class Pag e 12 Method Summary Class<?> getclassbeingredefined() 13 byte[] getnewclassbytes() 13 Pag e Constructor Detail ClassRedefinition public ClassRedefinition(Class<?> classtoredefine, byte[] newclassbytes) Create a new ClassRedefinition for the supplied Class Parameters: classtoredefine - - The class instance to redefine newclassbytes - - new bytes used to redefine the class. This array must not be modified by the caller after the ClassRedefinition is passed to the framework. Throws: NullPointerException - If either the class to redefine is null, or or the newclassbytes are null. Method Detail getclassbeingredefined public Class<?> getclassbeingredefined() getnewclassbytes public byte[] getnewclassbytes() OSGi Javadoc -- 06/09/10 Page 34 of 42

98 Interface RetransformingWeaver Interface RetransformingWeaver org.osgi.framework.weaving All Superinterfaces: WeavingHook public interface RetransformingWeaver extends WeavingHook A RetransformingWeaver is a special type of WeavingHook that obeys the limitations required for runtime retransformation of classes. These limitations require that the modified bytecode does not have any new, deleted, or modified method signatures; nor any new, deleted or modified fields; nor any change to the class's type hierarchy. RetransformingWeaver services will be called immediately after all WeavingHook services have been called, following the same ordering rules if multiple implementations are present in the service registry. Unlike WeavingHook services RetransformingWeaver services will also be called after any call to WeavingAdmin.reweaveClasses(Class...). Methods inherited from interface org.osgi.framework.weaving.weavinghook weave OSGi Javadoc -- 09/09/10 Page 35 of 42

99 Interface WeavingAdmin Interface WeavingAdmin org.osgi.framework.weaving public interface WeavingAdmin The WeavingAdmin allows a client to perform weaving tasks for the host bundle. Method Summary Class<?>[] boolean boolean boolean void void getallbundleloadedclasses(org.osgi.framework.bundle bundle) This method can be used to locate all of the classes loaded by a bundle ismodifiable(class<?> theclass) Used to find out whether the supplied class can be redefined or re-woven. isredefinitionsupported() Used to determine whether the framework currently supports class redefinition. isreweavingsupported() Used to determine whether the framework currently supports re-weaving. redefineclasses(classredefinition... classes) Redefine the supplied classes. reweaveclasses(class<?>... classes) Retransform the supplied classes. Pag e Method Detail getallbundleloadedclasses Class<?>[] getallbundleloadedclasses(org.osgi.framework.bundle bundle) This method can be used to locate all of the classes loaded by a bundle Returns: All the classes that have been loaded by this Bundle ismodifiable boolean ismodifiable(class<?> theclass) Used to find out whether the supplied class can be redefined or re-woven. Note that the output of this method is independent of the return value from isreweavingsupported() and isredefinitionsupported(). Parameters: theclass - The Class to check Returns: true if the class is allowed to be re-transformed, false otherwise isreweavingsupported boolean isreweavingsupported() Used to determine whether the framework currently supports re-weaving. This may return false if the framework, or the VM, or both do not have the relevant support. OSGi Javadoc -- 09/09/10 Page 36 of 42

100 Interface WeavingAdmin Returns: true if class reweaving is supported by the current framework. isredefinitionsupported boolean isredefinitionsupported() Used to determine whether the framework currently supports class redefinition. This may return false if the framework, or the VM, or both do not have the relevant support. Returns: true if class redefinition is supported by the current framework. redefineclasses void redefineclasses(classredefinition... classes) throws IllegalArgumentException, UnsupportedOperationException, NullPointerException Redefine the supplied classes. Any WeavingHook services present in the service registry are called to process the new bytes supplied in each ClassRedefinition. The resulting bytes after all WeavingHook instances have been called are cached by the framework. Next any RetransformingWeaver services are called to process the bytes output from the previous stage. As per the Javadoc for java.lang.instrument.instrumentation: This method operates on a set in order to allow interdependent changes to more than one class at the same time (a redefinition of class A can require a redefinition of class B). If a redefined method has active stack frames, those active frames continue to run the bytecodes of the original method. The redefined method will be used on new invokes. This method does not cause any initialization except that which would occur under the customary JVM semantics. In other words, redefining a class does not cause its initializers to be run. The values of static variables will remain as they were prior to the call. If this method throws an exception, no classes have been redefined. Parameters: classes - The classes to re-define Throws: IllegalArgumentException - If one or more of the ClassRedefinition objects is not modifiable. UnsupportedOperationException - If re-definition is not supported NullPointerException - If the classes array, or any entry in the classes array, is null. reweaveclasses void reweaveclasses(class<?>... classes) throws IllegalArgumentException, UnsupportedOperationException, NullPointerException Retransform the supplied classes. OSGi Javadoc -- 09/09/10 Page 37 of 42

101 Interface WeavingAdmin The previously cached output from the last class definition or re-definition should be used as input to the set of RetransformingWeaver instances, which are called in their defined order. The resulting bytes are then used to redefine the class. As per the Javadoc for java.lang.instrument.instrumentation: This method operates on a set in order to allow interdependent changes to more than one class at the same time (a retransformation of class A can require a retransformation of class B). If a retransformed method has active stack frames, those active frames continue to run the bytecodes of the original method. The retransformed method will be used on new invokes. This method does not cause any initialization except that which would occur under the customary JVM semantics. In other words, retransforming a class does not cause its initializers to be run. The values of static variables will remain as they were prior to the call. If this method throws an exception, no classes have been retransformed. Parameters: classes - The classes to re-weave Throws: IllegalArgumentException - If one or more of the classes supplied is not modifiable UnsupportedOperationException - If re-weaving is not supported NullPointerException - If the classes array, or any entry in the classes array, is null. OSGi Javadoc -- 09/09/10 Page 38 of 42

102 Interface WeavingHook Interface WeavingHook org.osgi.framework.weaving All Known Subinterfaces: RetransformingWeaver public interface WeavingHook This interface should be used to register weaving implementations within an OSGi framework Method Summary WovenClass weave(bundlewiring wiring, String classname, Class<?> classbeingredefined, ProtectionDomain protectiondomain, byte[] classbytes) Implementations of this service are called for one of two reasons: Pag e 17 Method Detail weave WovenClass weave(bundlewiring wiring, String classname, Class<?> classbeingredefined, ProtectionDomain protectiondomain, byte[] classbytes) Implementations of this service are called for one of two reasons: 1. The class is being loaded for the first time 2. The class is being redefined When called this method provides an opportunity to re-write the class bytecode that represents the class being loaded. WeavingHooks may also ask the framework to wire in additional dynamic imports to the bundle by adding an array of wiring Capabilities to the returned WovenClass object. If any of the packages cannot be dynamically imported, or any of the Capability objects do not represent a package, then the output of the WeavingHook will be ignored. If this method throws a ClassFormatError then class load will continue as if this method returned null, however the exception will be logged. This is a valid mechanism for reporting that the WeavingHook does not believe that the supplied class bytes meet its requirements. If multiple WeavingHook implementations are present in the service registry then they are called in the order in which the service registry returns them. The first WeavingHook is called using the raw class bytes, or the bytes passed to WeavingAdmin.redefineClasses(ClassRedefinition...). Subsequent services are called with either the bytes output by the previous service, or, if no bytes are output, the bytes input to the previous service. The resulting byte array produced by applying all of the WeavingHook services should be cached by the framework for use in calls to WeavingAdmin.reweaveClasses(Class...). Parameters: wiring - - The current wiring for the bundle classname - - The class name classbeingredefined - - The class being redefined, or null if this is an initial class definition protectiondomain - - The protection domain of the class classbytes - - The bytes to transform. This array must not be modified. Returns: A new WovenClass containing the replacement class bytecode and any necessary package changes, or null if the input bytes may be used unchanged. OSGi Javadoc -- 09/09/10 Page 39 of 42

103 Class WovenClass Class WovenClass org.osgi.framework.weaving java.lang.object org.osgi.framework.weaving.wovenclass public class WovenClass extends Object This class represents the output of a WeavingHook. It allows access to the class bytes, and to any additional packages that should be added to the bundle as dynamic imports Constructor Summary WovenClass(byte[] transformedbytes, Capability[] packagestoadd) Construct a new WovenClass Method Summary Capability [] getpackagestoadd() Retrieve the array of packages to add or null if no packages are to be added. byte[] gettransformedbytes() Retrieve the transformed bytes Pag e 15 Pag e Error : Refe renc e sour ce not foun d Error : Refe renc e sour ce not foun d Constructor Detail WovenClass public WovenClass(byte[] transformedbytes, Capability[] packagestoadd) Construct a new WovenClass Parameters: transformedbytes - - the transformed class bytes, may not be null. This array must not be modified by the caller after the WovenClass is passed to the framework. packagestoadd - - an array of packages that need to be added as dynamic imports to the bundle. This array must not be modified by the caller after the WovenClass is passed to the framework. Method Detail gettransformedbytes public byte[] gettransformedbytes() OSGi Javadoc -- 09/09/10 Page 40 of 42

104 Class WovenClass Retrieve the transformed bytes getpackagestoadd public Capability[] getpackagestoadd() Retrieve the array of packages to add or null if no packages are to be added. Java API documentation generated with DocFlex/Doclet v1.5.6 DocFlex/Doclet is both a multi-format Javadoc doclet and a free edition of DocFlex/Javadoc. If you need to customize your Javadoc without writing a full-blown doclet from scratch, DocFlex/Javadoc may be the only tool able to help you! Find out more at 9 Security Considerations Bytecode weaving offers malicious bundles the ability to inject arbitrary code into another bundle, and as such must offer a mechanism to secure bundles against malicious weavers. The basic security permission associated with weaving is a ServicePermission that allows a bundle to register a WeavingHook service. It should be noted that any weaver can modify the bytecode in any other bundle, and as such a malicious weaver can escalate its privilges to be the superset of all priviliges in the OSGi framework by picking the correct bundle to perform specific tasks. As such, a ServicePermission to register one of these services should be considered to be a similar risk to a bundle with AllPermission. 10 Document Support 10.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. Aspect Oriented Programming [4]. Instrumentation support for Java TM [5]. Java Persistence API OSGi Javadoc -- 09/09/10 Page 41 of 42

105 Class WovenClass 10.2 Author s Address Name Company Address Tim Ward IBM IBM UK Ltd, MP211, Hursley Park Road, Winchester, SO21 2JN Voice [email protected] 10.3 Acronyms and Abbreviations 10.4 End of Document OSGi Javadoc -- 09/09/10 Page 42 of 42

106 Compendium Design Documents OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Revision November OSGi Alliance.

107 Command Line Interface Draft 85 Pages Abstract This RFC describes a proposed specification for a Command processing interface for the OSGi Framework. Copyright OSGi Alliance 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

108 Command Line Interface Page 2 of 85 Draft November 12, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Problem Description Command Interface Requirements Non Functional Command Names Shell Shell Commands Source Providers Command Service Starting a Session Syntax Program Syntax and Semantics Built-In Commands Variables Redirection Parameter Annotation Invocation Evaluation Method Selection Finding the Command Argument List Objects, no Strings Strings Printing or Not Command Provider Discovery Other Commands Services and their Commands Closures Help Terminal Thread IO Service Child threads Multiplexing Copyright OSGi Alliance 2010

109 Command Line Interface Page 3 of 85 Draft November 12, Converter Service Formatter Service Javadoc Alternatives Security Considerations Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in 8.1. Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial 05 MAR 2008 [email protected] Additional text 03 APR 2008 Added a large number of sections, mainly booting and more details about the processing of scripts. Also completely changed the API and added a problem description and requirements section. Changes are so massive that it was not that useful to track changes (and I forgot anyway) New RFC 2009 April 21 Created a new RFC 147 to hold the command line interface design. RFC 132 will just be Framework Launching. Added issues 2010 May 16 Added issues found in GOGO and POSH Peter Kriens Ottawa 2010 Aug 30 Processed issues reported by Derek Baum and during the Ottawa meeting Copyright OSGi Alliance 2010

110 Command Line Interface Page 4 of 85 Draft November 12, 2010 Revision Date Comments Redwood 2010 Sep 16 Package Admin and Start Level need to use adapt. Check conversion of string -> class Converter specified to use calling do to load a class Remove shutdown and other OSGi commands. Standard OSGI commands. Pushed to another RFC. Made more clear that List and Map are literals and not java types All inherited methods are considered now Method names are first compared case sensitive and exact. if this does not provide at least 1 method, case insensitve compare is used. Annotations are not in 1.4 so argument/parameter matching works differently. That is, flags and options also do not work pre Java 5 Defined localization with Description annotations and a fallback with or without these annotations. service.ranking used to determine priorty for scope when multiple scopes with the same name are registered. Use String+ for osgi.command.function osgi.command.description overrides resources (or uses them) Help can work pre Java 5 using the resources Example with map literal used [] instead of <> Added converter from Dictionary <-> Map my:echo = {.. }? Works with the scope? Felix has a bug #2355 $0 is deleted Remove child threads... No InhertableThreadLocal In Terminal, moved attributes to interface level Removed ordering requirement in arguments. Sessions, named, and unnamed parameters can occur in any order. Renamed ifpresent and ifabsent to flag and absent Copyright OSGi Alliance 2010

111 Command Line Interface Page 5 of 85 Draft November 12, 2010 Revision Date Comments 1 Introduction This RFC is an solution for RFP 99 Command Provider. This RFC outlines the interfaces necessary to implement command line shells in OSG frameworks. 2 Problem Description This RFC addresses the problem of standardized external access. The purpose of this RFC is to enable a set of basic commands that are supported by all implementations, but it must enable that bundles can provide additional commands. 2.1 Command Interface There is a need for a service that allows human users as well as well as programs to interact with on OSGi based system with a line based interface: a shell. This shell should allow interactive and string based programmatic access to the core features of the framework as well as provide access to functionality that resides in bundles. Shells can be used from many different sources it is therefore necessary to have a flexible scheme that allows bundles to provide shells based on telnet, the Java 6 Console class, plain Java console, serial ports, files, etc. Supporting commands from bundles should be made very lightweight and simple as to promote supporting the shell in any bundle. Commands need access to the input and output streams. Commands sometimes need to store state between invocations in the same session. Copyright OSGi Alliance 2010

112 Command Line Interface Page 6 of 85 Draft November 12, 2010 There is a need for a very basic shell functionality in small embedded devices, however, the design should permit complex shells that support background processing, piping, full command line editing, and scripting. It is possible that a single framework holds multiple shells. The shell must provide a means to authenticate the user and the commands must be able to investigate the current user and its authorizations, preferably through standardized security mechanisms. To minimize footprint, it must also be possible to implement a shell without security. 3 Requirements 3.1 Non Functional Lightweight to allow shells for low footprint devices Allow shells with piping, background, scripting, etc. Make commands trivial to implement Make it easy to connect the shell to different sources. Provide an optional security framework based on existing security facilities Minimize the cost of a command (e.g. do not require eager loads of objects implementing commands) Support use of existing code by making a design that closely follows practices for command line applications in Java. 3.2 Command Names Provide a list of basic command signatures to manage the framework so they are consistent among implementations. 3.3 Shell Provide interface to execute a string as command Allow other bundles to implement commands Allow other bundles to provide a connection to: telnet, console, serial port, etc. Provide help for each command Provide a means to disambiguate commands with the same name Provide a means to disambiguate when there are multiple shells Copyright OSGi Alliance 2010

113 Command Line Interface Page 7 of 85 Draft November 12, 2010 Authenticate the user Provide programmatic access to the shell, that is, a program generates the commands. 3.4 Shell Commands Read input from user or previous command Write output to user or next command Allow sessions, i.e. group commands over a period of time, allowing them to share state Provide usage information of the command Allow commands to be protected with permissions Provide access to he authenticated user via User Admin (though User Admin may not be present) Optional: Allow computer readable meta information about the commands to support forms Optional: Provide formatting rules + library to standardize look and feel for output. This could consist of routines to show tables in a consistent form. Commands should not have to do low level parsing of command line arguments. Commands should be able to have access to the command line arguments Commands must be able to get access to the console input Commands must be able to use the keyboard input stream 3.5 Source Providers Provide an easy way to allow bundles to connect the shell to sources like telnet, serial ports, etc. 4 Technical Solution The designs in this section are to be part of the Compendium Specifications. The drivers of this design have been: Core Engine Implementable in < 30k Very easy to add new commands Copyright OSGi Alliance 2010

114 Command Line Interface Page 8 of 85 Draft November 12, 2010 Leverage existing mechanisms The basic idea of the design is that there are a number of components parts. The bundle that interacts directly with the user. This bundle handles the IO streams and parses out one or more lines of text, called the program. This program creates a Command Session from the selected Command service. This IO processor then gets a command from the input and gives it to a command session execute method. The command session parses the program, and executes it. The session then returns an Object result. The command is executed synchronously. The shell will execute all commands in the program. These commands are implemented by services. A service can be registered with list of COMMAND_FUNCTION properties. These properties list the commands (potentially wildcarded) that a service can provide to the shell. These functions do not require a specific prototype, the shell matches the parameters to the function using parameter coercion. The type information available in the reflection API is used to convert the strings in the input to specific types. Each command can print to System.out and it can retrieve information from the user (or previous command in the pipe) with System.in. Each command can also return an object. A Terminal objects is available to interact with a terminal. Therefore, the Command Shell service consists of three distinct parts: Command Processor service - This service is used by bundles that can connect the shell to an outside interface like: Telnet, Console, Web, SSH, etc. These bundles provide streams or a Terminal service and get a Command Session in return. The session is then used to execute their commands. Copyright OSGi Alliance 2010

115 Command Line Interface Page 9 of 85 Draft November 12, 2010 Command Provider service - Command implementations can register this service to provide commands. Commands are methods on the service. The names (and help) of the methods can be listed through properties. There is no actual Command Provider interface because a service property allows any service to provide commands. Converter Service Provide facilities to convert from strings to specific types and from specific types to strings. Formatter Service Provides a facility to format objects as strings with three levels of detail. ThreadIO Service - Commands can use System.in, System.out, and System.err to interact with the user. However, this requires that different commands are separated in their output. This RFC therefore defines a service (likely a Framework service) that can multiplex the System IO streams. 4.1 Command Service The command service consists of the following interfaces CommandProcessor The engine is running the scripts. It has no UI of its own. A UI (telnet, web, console, etc, is expected to create a session from this engine. The Command Processor service is registered by the implementer of the script processor. CommandSession The command session represents the link between a UI processor (e.g. telnet) and the command processor. It maintains a set of variables that can be set by the UI processor as well as from the script. Commands should maintain any state in the session. The session is also associated with a keyboard stream as well as a console stream, represented by a Terminal object. This allows commands to directly talk to the user, regardless if they are piped or not. Function A function is an executable piece of code. Commands providers can add Function objects to their arguments and execute them. This allows commands that implement iteration blocks, if statements, etc. MetaScope Provides access to meta-information about to the sub-commands of a scope. The Command Session can provide a list of Meta Scope objects. Terminal An interface to a terminal allowing clients to control the cursor and attributes of the screen.it represents the input, error and output stream. ArgumentList A list of arguments that is expanded when processing a command line and such an object is an argument. 4.2 Starting a Session A user of the Command Processor must create a Command Session to use the script. The following code executes a small program, assuming it is injected with a CommandProcessor called cp: ByteArrayOutputStream bout = new ByteArrayOutputStream(); CommandSession session = cp.createsession(system.in,bout, System.err, null); Copyright OSGi Alliance 2010

116 Object result = session.execute( bundles grep aqute ); String s = new String(bout.toByteArray()); Command Line Interface Page 10 of 85 Draft November 12, 2010 In this case the session is created on a set of streams. It is also possible to create a session with a Terminal. A Terminal has representations of the standard streams (well, writers and a readline/getin methods) but provides additional capabilities to control the screen is color, attributes and position of the cursor. If there is no terminal provided, the Command Processor service must provide a default terminal. The current terminal can be obtained with getterminal() Syntax The tsh language requires a very simple parser to keep its footprint small. Basically a command line is broken into tokens, where the rules to parse a token are quit simple. These tokens are then each evaluated. The resulting list is then executed. Depending on patterns in this list it is either a command execution, a method call, a variable assignment, or a variable removal. Command execution and method calls use the Java type information to coerce the parameters to the target types. Some examples: $ echo Hello World Hello World The first token is the command name because it is a simple string, and is a command. Objects implementing a command (that is, having a method with a command name) are registered as a variable with a structure. The same object can be registered under many different names. That is, if an object implements ls and cd, then it is registered as file:ls, and file:cd. As can be seen in this example, the actual name of the command is a structured name consisting of a <scope> and a function name, separated by a ':'. I.e. in the earlier example the command '*:echo' is searched because the scope is not defined. In the hello world examples, the execute method is called on this object with two CharSequence parameters: [ Hello, World ]. Because the number of arguments of echo is variable, it is declared with an array of Object. public CharSequence echo( Object args ) { StringBuilder sb = new StringBuilder(); for ( Object arg : args ) sb.append(arg); return sb; Methods can print to System.out, but are normally expected to return an object. Returning an object allows the result to be used in other commands as well as reuse centralized formatting. tsh will print out the object to standard out if it is not used as a value in another command unless it is null, for example with piping. If a program contains multiple statements, only the last value is printed out. Formatter services are used to print out the objects in a proper format Program Syntax and Semantics The syntax of the shell should be simple to implement because the framework must provide a parser for this syntax. On the other hand, a more powerful syntax simplifies the implementation of the commands. For example, when Microsoft introduced a command line shell, it did not support piping. As a consequence, each command had to implement functionally to page the output. There are other examples like handling of variables, executing subcommands, etc. The shell syntax must also be easy to use by a user. That is, a minimum number of parentheses, semicolons, etc. Some compatibility with the Unix shells like bash is desired to for users to not have to learn completely new Copyright OSGi Alliance 2010

117 Command Line Interface Page 11 of 85 Draft November 12, 2010 concepts. Then again, the current popular shells have a convoluted syntax because they added more and more features over time. Also, shells like bash are very much text based while the use of actual objects is highly desirable. An OSGi shell syntax can rely 100% on the fact that there is a Java VM. This makes it easy to control the framework and implement a shell with Java. However, a shell implies that the users directly type the commands as they go. The requirements for a shell are therefore different than the requirements for a programming language. However, in contrast with a shell like bash that must be totally text based, it seems a waste not to tie the shell language closely to the Java object model. Though there are many script languages, there seems to be no shell language for Java that provide such a syntax. Jacl comes close but has the disadvantage that it brings its own function library derived from tcl. Beanshell comes close from the other side but has a syntax that is virtually the same as Java, which contains a lot of cruft characters. A new syntax can reuse the concepts of tcl but tie the language close to the Java language. I.e., no need for separate function libraries. The syntax and dependencies are defined in an ANTLR file for now. The specification will write out those rules in more detail.by keeping this in the ANTLR it is easier to verify changes, however, there is no reason to implement an actual tsh with antlr, the format is only used for documenting. grammar { package output; { package output; } // // The pipe's have higher precedence so a program is a collection of // pipes separated by newline or semicolons. It is allowed to // have no pipe after the last semicolon/nl // tsh : program ; program : pipe (separator (pipe ))* ; // // A pipe consists of statements separated by a vertical bar. Each statement // must be executed in a separate thread. The System.out of an earlier // statement must be connected to the System.in of a later statement. The first // statement has the current Terminal as input and the last statement must have // the Terminal as output. The value of a pipe is the result of the last // statement. If a statement that is not the last statement returns // an object than this object must be formatted and send to System.out. // pipe : statement ( ' ' statement )* ; statement : TOKEN '=' pipe // Assignment TOKEN '=' // Remove var TOKEN value* // Command (scope:function) value+ // Method invocation ; // // A core aspect of tsh is the concept of a value. A value is thought of // as a string that can be evaluated to provide an object depending on // its type. The type is defined by its first character. The following Copyright OSGi Alliance 2010

118 Command Line Interface Page 12 of 85 Draft November 12, 2010 // types are defined: // value : TOKEN // Simple token STRING // Single or Double Quoted '{' program '}' // Closure '(' program ')' // Evaluate '[' value* ']' // ArrayList '<' ( value '=' value ) * '>' // LinkedHashMap '$' TOKEN // basic macro '${' TOKEN ( ':' value )? '}' // braced macro '$(' program ')' // program macro ; // // Specifies the separator when there are multiple pipes. // separator : ';' '\n' COMMENT; // // A single or double quoted string. Double quoted strings are // expanded with macros, single quoted not. A string can contain // virtually any character except its start character including // newlines. Escaping for the quotes and other escapes are supported. // STRING : '\'' (ESC_SEQ ~('\\' '\''))* '\'' '"' (ESC_SEQ ~('\\' '"'))* '"' ; // // The TOKEN is the basic element of a command line. A TOKEN is // very liberally specified to be a sequence of one or more characters that // is not SPECIAL to this parser. // TOKEN : ~SPECIAL+ ; fragment SPECIAL : '\u0000'..'\u001f' '#' ' ' ';' '=' '{' '}' '(' ')' '$' '<' '>' '[' ']' ' ' Copyright OSGi Alliance 2010

119 Command Line Interface Page 13 of 85 Draft November 12, 2010 '"' '\''; // // Comments start with # and are ignored. // COMMENT : '#' ~('\n' '\r')* '\r'? '\n' ; // // Whitespace is defined as spaces and tabs. // WS : ( ' ' '\t' '\r' )* {$channel=hidden; }; // // Escaping // \b = backspace 08h // \t = tab 09h // \n = newline 0Ah // \f = formfeed 0Ch // \r = return 0Dh // \\ = backslash 5Ch // \' = squote 27h // \" = dquote 22h // \\n= skipped // fragment ESC_SEQ : '\\' ('b' 't' 'n' 'f' 'r' '\"' '\'' '\\' '\n') UNICODE_ESC ; fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ; fragment HEX_DIGIT : ('0'..'9' 'a'..'f' 'A'..'F') ; The previous syntax is rather extensive to be able to describe the semantics. However, TSH can rather easily be parsed in an unstructured way. The input can be very easily tokenized, where the closure, execution, list, and map must ensure that they match their respective end tokens correctly and ensure that their start character is ignored inside strings. For example, { { { {{{ } } } would be a single closure. A statement is a collection of tokens without ' ' or ';' (or newline) symbols. A pipe is a collection of statements separated by the ' ' symbol and a program is a set of pipes Built-In Commands Built-in commands are in the built-in scope. Object new(string fqn, Object args) Create a new object. The fqn is the fully qualified name and the args are given to the constructor. The class is loaded through the bundle that got the CommandProcessor service. Copyright OSGi Alliance 2010

120 Command Line Interface Page 14 of 85 Draft November 12, 2010 void cat(uri..file) Copy a file to the stdin. This command replaces the Unix shell IO redirection. The URI is relative to the current working directory, see cwd variable. String tac(uri...file) Copy a file from stdout, the return is the contents of the output. This command replaces the Unix shell IO redirection. The URI is relative to the current working directory, see cwd variable. Object eval(string) Evaluate a string as a script and return the result of the last statement. Object eval(object[]) - Evaluate a list of raw values. ArgumentList args( Collection ) - Return an argument list from a collection. This list will be expanded when used in a command line. void addcommand(string scope, Object object, String functions ) - Add a new command to this session only. If no functions are specified, all public methods in the object are used. Object global(string,object) Set a global variable in the shell. This variable must be persistently stored. URI cd(uri path) - Switch the directory indicated by path, relative to the cwd. Path can be an absolute URI, in that case the cwd becomes that URI. If path starts with a slash, it is an absolute file path. The path '..' indicates parent directory, the '.' indicates current directory. The return is the new working directory. The current working directory is available via the ${cwd} session variable. MetaScope help(string scope) Answer the first MetaScope with the given name Collection<MetaScope> help() - Answer all Meta Scopes Object if(object, Function) Execute function if Object does not evaluate to true. False is a number 0, FALSE or null. The return value is null when not evaluate or the result executing the function Object foreach( Collection, Function) Call the function for each object in the collection, return the result of the last invocation or null if no element was found in the collection Variables There are the following variables (in order of priority): 1. Session Variables that are set with the assignment operator ('=') always set the session variables. Session variables are local to the session and not shared with anybody else. 2. Global The command processor maintains global variables that are shared between all sessions. These variables are consulted if the session has no value for a given name. Global variables can be set with the global command. Implementations may throw a security exception. 3. Framework If a variable cannot be found in the session or in the global variables then the framework is asked for the variable. 4. System Properties If the Framework also cannot define a value the System properties are used. The Command Processor maintains a map with all global variables, this Map can be obtained with CommandSession.getGlobalVariables. The session variables are available through a getsessionvariables() Copyright OSGi Alliance 2010

121 Command Line Interface Page 15 of 85 Draft November 12, 2010 method. Framework variables or system properties cannot be directly set, they are filled by the Command Processor to provide share variables between sessions. Session variables provide locally added or modified commands, variables set in the command line, or variables managed by commands. Session variables are transient, they are not persistently stored, global variables that are set with the global command must be maintained persistently. The following built-in session variables provide general features: CWD (URI) Current working directory. The current working directory is maintained as a URI. If no scheme is given, the URI represents a File path (with always forward slashes). Built-in command cd is used to modify the URI. SCOPE (LIST modifiable) A list of scopes, similar to Unix PATH. Shells should throw an exception if an attempt is made to override these variables with the wrong type Redirection Piping seems to introduce a significant complexity in the command processing. However, it turns out that it can be implemented with very little code that easily outweighs the advantages if the increased simplicity of the commands. The key example is of course the less or more command. Many of the other commands can generate output that is too much to fit the screen. Using piping, the output can be paged through a centralized command. Functions like grep, uniq, etc. are all impossible without piping. Normal unix shells have IO redirection. It was chosen to not implement this, but instead use commands. There are two commands that can redirect io: cat <uri>+ tac <uri> concatenate files and pipe to output receive input and store it in file or return object That is, to get the output of bundles as a string in a variable: output = bundles tac Parameter Annotation For Java 5 and later VMs, a set of annotations are available that provide help information and that provide information to for named parameters, a default value, and in case of an option, if the option can be repeated. A named parameter is a parameter that has a Parameter annotation that specifies one or more aliases. A named parameter is either a flag or an option. A flag has no argument while an option must be followed by an argument. The Parameter annotation can also provide a default for unused parameters. This distinction is made with the absent and flag attributes in the annotation. The absent attribute specifies the value of the parameter when the name parameter is not specified in the arguments. The flag attribute specifies the value of the parameter when the flag is specified in the arguments. Setting the flag attribute makes the named parameter a flag, not setting it makes it an option. For a flag, the flag attribute is set, thereby providing a value for the parameter when the flag is found. If the flag attr. is not set, the arguments must provide a value for parameter. void alias = { -v, --verbose }, flag= 2, absent= 0 ) int alias = { -f, --file }, absent= default.txt ) File file ); Copyright OSGi Alliance 2010

122 Command Line Interface Page 16 of 85 Draft November 12, 2010 $ foo -v == foo(2, new File( default.txt )) $ foo -f /tmp/test.txt == foo(0, new File( /tmp/test.txt )) Some options can be repeated multiple times, this can be specified with the repeatable attribute. The parameter type must then accept conversion from a list: void alias = -x, absent= <<null>>, repeatable=true ) String[] xs ) $ foo -x abc -x def -x ghi == foo( new String[] { abc, def, ghi } ) It is also possible to provide default values for parameters that are not named. Those Parameter annotations must not specify an alias. void alias = -x, absent= <<null>>, repeatable=true ) String[] xs ) $ foo -x abc -x def -x ghi == foo( new String[] { abc, def, ghi } ) Annotations do not allow defaults of null. For this reason, the Parameter annotation has the following constants defined: NOT_SET Defines that there is no value set NULL Defines the value for null These annotations only work on 1.5 and later Vms. For 1.4 Vms, each argument must be specified without options and flags. Description Annotation The description annotation provides the following attributes: value The main description. This description can be quite verbose using line feeds. summary A summary of the element. Should be one line, no returns/line feeds. The Description annotation works on types, methods, and parameters. For Fantastic method with great options ) void foo(); The Description annotation can be localized per scope. The base name of the localization Properties resource is: OSGI-INF/l10n/command.<fqn> Where fqn is the fully qualified name of the object that carries the annotation. If the anntation uses a value that starts with a % (no preceding spaces) then the percent sign is removed and the remainder of the value looked up as a key in the resources. For %foo.description, summary= %foo.summary ) This will lookup the key foo.description. If no Description annotation is found, or the description annotation does not specify a requested attribute, then the shell must use the following default ids for the resources: <method-name>.<index>.description <method-name>.description for a parameter description for a method description Copyright OSGi Alliance 2010

123 Command Line Interface Page 17 of 85 Draft November 12, 2010 description For summaries, the suffix is.summary. for the class/scope description Invocation In the end, a statement consists of a collection of parsed raw values, this collection is called the arguments. The arguments consists of all parts that were presented as a pipe in the grammar. During invocation, at first the arguments are the raw input. An argument can have a different type depending on its lexical value: 1. TOKEN 2. Closure 3. Execution 4. STRING 5. Argument List 6. List (ArrayList) 7. Map (LinkedHashMap) 8. Macro Reference Before a command is executed or a method invoked, the shell must look at the types of the arguments before evaluation and detect the pattern that is used for a command.there are a number of distinct cases in priority order: 1. TOKEN '=' pipe The assignment pattern consists of an assignment operator with a pipe. 2. TOKEN '=' - The variable removal pattern 3. TOKEN value+ - Command execution 4. value value value* - General method invocation These patten must be detected before the raw arguments are evaluated because the evaluation will loose an important distinction: it is possible that a value is evaluated to a general string making it impossible to distinguish between them. For example, the statement abc length will map to the general method invocation while abc length maps to a command execution. After evaluation, they're equal. The next step is therefore to evaluate all arguments (including the first). Evaluating has the following meaning for the different types: 1. TOKEN Evaluates to String with its contents 2. Closure Evaluates to an object implementing Function 3. Execution The contents inside the parentheses are executed as a program. The resulting value is the value of the last pipe. Copyright OSGi Alliance 2010

124 Command Line Interface Page 18 of 85 Draft November 12, STRING The value is the value of the string with any escaping applied. If it is a double quoted string, macros must be replaced as well. 5. Argument List Take each member of the list as an evaluated value and add it as a new argument. This is used to implement the special behavior of $*. It allows a closure to expand its arguments for a new command. Though $* does not implement ArgumentList, it is easy to expand with the args() method: (args $*) 6. List The list consist of a set of values. Each value must be evaluated and added to an ArrayList. This is a concrete class because it is the implementation used for the literal list specified with a '[' and ']'. This list is converted, if necessary, to the target type. 7. Map The lists consists of a set of entries, where an entry is a value=value. Each entry must be evaluated and added to a LinkedHashMap.This is a concrete class because it is the implementation used for the literal map specified with a '<' and '>'. This list is converted, if necessary, to the target type. 8. Macro Reference Macro references must be replaced with their value. See macros. Arguments can refer to changing values, it is therefore important that the evaluation for each pipe takes place just before it is invoked. After the evaluation, the shell has a collection of evaluated arguments. For example: $ foreach (bundles) {echo($it location)} This command first creates the following collection of raw arguments: 1. TOKEN 'foreach' 2. Execution 'bundles' 3. Closure with value 'echo($it location)' After evaluation, the arguments looks like: 1. String: 'foreach' 2. Bundle[] 3. Function This collection is now executed based on the earlier detected pattern. 1. Assignment first argument is the name of the variable. The evaluated objects after the equal sign are a pipe. This pipe must be evaluated to get the value, this value is assigned to the given variable. For example: bs = (bundles) length. 2. Removal Remove the variable with the name of the first argument, for example: bs = 3. Command The first argument in the collection is the name of the command. This name can contain a scope or not. See Finding the Command 4. Invocation The first argument is the object, the second value. For example: $abc length. In the case of the Command and the Invocation case it is necessary to map the remaining arguments to the parameters of the method invocation. In the case of the command call, the arguments after the command name Copyright OSGi Alliance 2010

125 Command Line Interface Page 19 of 85 Draft November 12, 2010 are all method parameters because the command name implies an object and method, in the case of an invocation the values after the object and the method name are values. When a Java method is called, it is necessary to match the arguments to the method that has the best parameters to match those arguments. This requires that parameters are converted to their correct type Evaluation Assume we have a target object t. If the execution is about a command, t is found from the command name. If the case is the invocation then t is the evaluated first value. Next the method m must be selected. In the command case, m is implied by the command name as described in provider discovery. In the invocation case m is the second evaluated value. So, $abc $def will invoke the method in $def on the object in $abc. This means that the matching algorithm consists of finding the best method m on object t with matching name n, that is eligible for the given arguments. Object eval( Object t, String n, List<Object> arguments ) 1. Create a list with matching methods as given by t.getclass().getmethods() and filtered by the osgi.command.function list. This list is the set of methods whose names match the command name exactly. 2. If this list is empty, create a list with eligible methods. A method is eligible if its name matches the method name. The method name matches if: 1. Case insensitive match with a _ prefix. E.g. the argument is new, this will then match _new. 2. Case insensitive match 3. Apply the bean design pattern to the method name and compare the name of the property in a case insensitive way. That is, a command like bundles must find the method getbundles and setbundles and isbundles. See the beans design patterns for proper converting a name to a getter. The bean name is compared case insensitive. 3. Sort this list on: 1. cardinality, higher cardinality, must be earlier in the list, if equal: 2. parameter annotations, with parameter annotations must be earlier in the list, if equal: 3. varargs, without varargs must be earlier in the list, if equal: 4. canonical names of the parameter type classes, a lower name must be earlier in the list Method Selection For the method selection it is necessary to match the arguments against the parameters of the method. For this purpose, a parameter has different qualities: issession The target type is CommandSession ismandatory Parameter annotation missing absent not set isoption isnamed() && flag not set isflag isnamed() && flag set Copyright OSGi Alliance 2010

126 isvarargs last parameter of a varargs method isrepeat Parameter annotation present && repeat set to true Command Line Interface Page 20 of 85 isnamed Parameter annotation present && at least 1 name in alias Draft November 12, 2010 For each eligible method it is now necessary to see if the arguments could be mapped to this method. So for each method in sorted order: 1. Create an array for the parameters ps 2. For each argument 1. if the argument is a string and starts with - then 1. remove argument from arguments 2. if argument is --, break. no more parsing of named parameters in the arguments 3. find the parameter info for the named parameter, then treat it as a serie of single character named parameters. Each of those MUST be found. 4. Repeat the following for each parameter 1. if a flag value is set, assign this to ps[ parameter index ] 2. else remove the next argument and assign this to ps[parameter index] The arguments have not been cleaned up of any named parameters and the results are already set in ps. For example: void foo( CommandSession alias = { -v, --verbose }, flag= 2, absent= 0 ) int alias = { -x, --extra }, flag= true, absent= false ) boolean alias = { -f, --file }, absent= default.txt ) File file, String input ); $ foo -v abc -f x.tt Initially, the arguments are: [ -v, -f, x.tt, abc ]. After the prior cleanup step, the result is now: ps[] = new Object[5]; ps[0] = null ps[1] = 2 ps[2] = null ps[3] = x.tt ps[4] = null arguments = { abc } After this cleanup, defaults must be applied. 1. ps[last] = [] 2. For each parameter index Copyright OSGi Alliance 2010

127 1. if ( parameter type == CommandSession), insert it, continue 2. if ps[index] is not set Command Line Interface Page 21 of 85 Draft November 12, if named parameter, then use absent value. If no absent attr. set, then this is an error (mandatory) 2. else 1. if arguments is not empty, use next argument for ps[index] 2. else if there is a parameter annotation with an absent value, use that one. If arguments are left over, then this list of arguments cannot be matched to the method so this method is ignored. In the next step, each of the values in ps[] must be converted to the appropriate parameter type using the Converter. If this conversion fails, the method is not applicable. The first method that succeeds with this process is invoked. If no suitable method can be found and a main(object[]) method is available then this method must be called. The whole command line must be given, where the first parameter must be the name of the function including its scope (even if it was not specified on the command line). If none is found, a NoSuchMethodException must be thrown Finding the Command Finding a command must use the SCOPE variable. The SCOPE variable is a List<String> with scope names. 1. If the command name contains a scope, 1. Look up the command name from a service as described in Command Discovery. 2. Lookup the command as a variable in the session variables 3. Look at the built-in commands 2. Otherwise, for each scope name in the variable SCOPE, add the scope name to the command 1. look up the command name from a service as described in Command Discovery. 2. Lookup the command as a variable in the session variables 3. Look at the built-in commands 3. Lookup the command as a variable in the session variables 4. Look at the built-in commands, ignoring the prefix Argument List There is a special interface that changes the behavior of the command line processing: Argument List. A Argument List is a a List<Object>. The special behavior is that when a Argument List is used as a raw value, its content must be treated as a list of evaluated arguments. These evaluated arguments must be expanded in the list that is being processed. A normal List can be turned into an argument with the expand method. For example: Copyright OSGi Alliance 2010

128 $ g = { grep -i (args $*) } // $ g pattern file // grep -i pattern file Command Line Interface Page 22 of 85 Draft November 12, 2010 Any list that implements this interface will expand its contents into the array of arguments. The $* is a normal list and will this not automatically be expanded. It is also a mutable list which allows for alternative manipulations: $ g = { $* add 0 -i ; grep (args $*) } // $ g pattern file // grep -i pattern file Objects, no Strings Arguments are not strings, they are proper objects after evaluating. Variables can refer to objects, arrays are objects, and also the result of a direct command (using parentheses ()) can result in a proper object. Matching these objects to a method is non-trivial Strings TSH supports two types of Strings: single quoted and double quoted. Double quoted strings can contain macros. A TSH implementation must replace the macros with their value when the statement's parameters are evaluated. This must happen for every evaluation so that the macro always reflects the latest value. There are two types of macros: ${ } - Braced macros can contain a TOKEN as variable name and will be replaced with the actual variable value. ${ name ':' default } - The special construct allows a default value to be specified if no variable value is found. $( ) - Parentheses indicate that the macro is actually a parenthesized value and must be evaluated. To use a string like ${ or $( in the double quoted string, escape the $ like This is a macro: \$(...) Printing or Not In principle, tsh must only print the object when it would otherwise gets lost. It will therefore only print the object when a command is piped because in that case there is nobody to use the resulting object. In all other cases, the object is returned and not printed. If an object is printed, it must use the Aggregate Formatter service with level INSPECT Command Provider Discovery Command Provider discovery is based on the OSGi service model. Any service can be used as a command provider. Dedicated command providers must register their service with two properties: osgi.command.scope - This property defines the name of the command provider. This name is not normally used because the function names are unique. However, if the function names are no longer unique, then this scope can be used to disambiguate. Copyright OSGi Alliance 2010

129 Command Line Interface Page 23 of 85 Draft November 12, 2010 osgi.command.function - The name of the function. This is a String+ property, so many names can be listed. This function name should match to a public method in the service object. If no function list is provided then the shell must get the functions by analyzing the class of the service object and using all public methods. osgi.command.description A description of the scope For example, the following code is a DS that provides a few utility commands: } public class Tools { public void grep(string match) throws IOException { Pattern p = Pattern.compile(match); BufferedReader rdr = new BufferedReader( new InputStreamReader(System.in)); String s = rdr.readline(); while (s!= null) { if (p.matcher(s).find()) { System.out.println(s); } s = rdr.readline(); } } public void echo( Object[] args) { StringBuffer sb = new StringBuffer(); for ( Object arg : args ) sb.append(arg); } System.out.println(sb); The properties provide sufficient information for the Command Shell to find the providers. Note that it is not necessary register the service as a Command Provider, the properties suffice. This makes it possible to register these properties on an existing service. For example, the Configuration Admin could just register the following properties: osgi.command.scope = 'cm' osgi.command.function = { 'createfactoryconfiguration', 'getconfiguration', 'listconfigurations'} This will enable shell scripts like: cfg = configuration com.acme.pid $cfg update <port=23 host= Or, for the Log Service command.scope = 'log' command.function = 'log' log 2 hello world If multiple services register with the same scope name then they must be sorted in service.ranking order. The Command Session's owner must be used for getting the service objects. That is, the bundle that uses the service must be the same as the bundle that got the command session. Copyright OSGi Alliance 2010

130 Other Commands Command Line Interface Page 24 of 85 Draft November 12, 2010 Any other commands can be added to the shell by storing them in the session, for this purpose there is a builtin in addcommand function. Command names are scoped like <scope>:<function>. The value of this variable can be a plain object, or it can be an instance of Function. If it is an instance of Function, it can be directly executed. Else, the method with the function name is called upon it Services and their Commands Implementations of services are recommended to provide commands for their service, this is quite straightforward and described in a later section. For example, assume that the implementation of the Configuration Admin has registered its method as commands. I.e. all its public methods are available. $ my.pid = configuration my.pid; $my.pid update <port=5012 host= > The configuration command is executed against the Configuration Admin service. This returns a Configuration object. In this case, it is stored in the my.pid variable. In the next statement, we call the update method on the Configuration object and set a dictionary. Ok, one more example, based on the fact that the Configuration Admin is available as commands: $ listconfigurations (service.pid=com.acme.*) grep port Closures The proposed specification of tsh also has closures. Closures represent a program that can be evaluated later. They start with a '{' and end with a recursively matching '}'. Closures can be injected as a Function in the called method. Closures implement the Function interface. The follow code will add a command written in tsh: $ my:echo = { echo xx (args $*) xx } Closure... $ my:echo Hello World xx Hello World xx A closure provides a facility for delayed execution. A closure starts with a '{', it can contain a complete program, and ends with a '}'. If evaluated it will be turned into an object implementing the Function interface. A Function can be executed with parameters. A Function can be invoked many times if needed. A closure has access to its parameters via the following macros that are only valid inside the closure: $0 error $1..$n parameters in the given sequence, 1 is first parameter. $it equals to $1 $* Mutable List<Object> that contains parameters $1.. $n Help The Command Processor has extensive information about the possible commands. This information is made available through the getmetascopes() method on the Command Session. This method returns a snapshot of the collection of MetaScope objects. These objects are derived from the meta information of the scopes. It can come from: Copyright OSGi Alliance 2010

131 Command Line Interface Page 25 of 85 Draft November 12, The osgi.command.description property on a command service. A property has the highest priority for the scope description. If not set, the Description annotation or the resource information must be used. 2. The name of the methods, the return type, and the parameters method types 3. The Descriptor and Parameter annotations. If both a property and a annotation is used, then the annotation must wins. If multiple scopes use the same name, then the descriptive texts must be concatenated with two newlines separating them. If no annotations are used, the descriptive help information can also be found in the resources as described with the annotations Terminal The Terminal class represents the output terminal or console. The terminal is either created by the Command Processor or, when the IO Handler passes streams end their encoding, or is created by the IO Handler. Whatever route is taken, the primary interface for IO in the shell is the Terminal. The IO Handler can interface to many different types of terminals. From simple ASCII terminals to high level graphic windows. The capabilities can therefore differ significantly, this is reflected in the getcapabilties() method. This method returns a bitmap of capabilities. Any terminal must support the ASCII code set and report and allow simple cursor movements. Even the most primitive ANSI terminal supports this and these movements can be emulated on even the simplest terminal. A Terminal is associated with two Print Writer objects: System.out, System.err. Input is obtained from two methods: int getin() and String readline(). Normally, commands will use the System.{out,err,in} objects to do their output. It is only in special cases that the extended capabilities of the Terminal are needed. Using the Terminal will bypass any piping that was set up. The Command Processor must ensure that the System.* streams, which use the default encoding, are properly converted to the Terminal writers. The Terminal interface provides a number of methods that can be used to control where and how the output stream ends up on the terminal. There are a number of methods that can query the terminal for its characteristics and there are a number of methods that can change the state of the terminal. Not all methods work on all terminals, the getcapabilities() method can inform the caller about any capabilities. The terminal can report its width and height. The screen of the terminal should be see as a table with rows and columns from [0,width) x [0,height). The left-top of the screen is position 0,0 and the right bottom is width-1, height-1. Any text displayed on the screen will not wrap but will be ignored when displayed beyond the bounds. Terminals may change the last character to indicate this cut-of. The cursor (the place where any new text on the output Print Writer will be displayed) can be positioned with tge setposition() method, which takes an x and y coordinate. The current output Print Writer must be flushed before the position is altered. The current position can be queried with getposition(). Terminals can support a number of attributes that alter the way the screen is displaying the text. The setattributes(attribute[]) method sets these attributes and return the current attributes. This is in association with the output Print Writer, not the screen position. Any subsequent writes will be displayed with the new attributes. The method returns an array of attributes which represent the previous set of attributes. Passing this array to setattributes() will restore the previous state. Copyright OSGi Alliance 2010

132 Command Line Interface Page 26 of 85 Draft November 12, 2010 Terminals can support bi-directional text. Unicode characters have an associated direction. Terminals are not required to support bi-directional text. However, if they support bi-directional text then they must ensure that horizontal cursor movements and the movement caused by forward() and backward() are properly synchronized. That is, when the CURSOR_FORWARD is reported then forward() called, the forward method must adjust the movement depending on the direction of the underlying text. The same for CURSOR_BACKWARD and backward(). It is assumed that the underlying logic to calculate the direction is handled in a similar was as the java.text.bidi class. In all cases, the left-top of the screen remains 0,0 and the default progression is always left-to-right. 4.3 Thread IO Service The Thread IO service is a framework service that guards the singletons of System.out, System.in, and System.err. It maintains a stack based model of streams per thread. Any party that wants to receive output or provide input on the current thread can push its streams. The ThreadIO service consists of two methods: pushstreams(inputstream,printstream,printstream) Push the given Associate the given streams with the current thread. Any output on the current thread using any of the System Print Streams will in effect be redirected to the appropriate system stream. Input will come from the given input stream. This method can be repeated multiple times for a thread. That is, an implementation must stack the streams per thread. Streams may be null, in that case they refer to the last set stream or the default if no streams are set. pop() - Cancel (or pop) the streams from the thread local stack. If no more streams are available, use the value of the original System streams. Usage of the Thread IO service is very straightforward but care must be taken that exceptions do not leave streams on the stack. For example, the following code grabs the output: String grab(threadio threadio ) { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream pout = new PrintStream(out); threadio.pushstreams(null,pout,pout); try { System.out.println( Starting... ); dowhatever(); System.out.println(... Done ); } catch(throwable t ) { t.printstacktrace(); } finally { threadio.pop(); } pout.flush(); return new String( out.tobytearray() ); } Child threads Child threads created by commands must not inherit the stream from the parent thread. They must default the to the original streams. Copyright OSGi Alliance 2010

133 4.3.2 Multiplexing Command Line Interface Page 27 of 85 Draft November 12, 2010 Multiplexing will not be in this release. Once we've decided what to do with general multiplexing then we should add this. 4.4 Converter Service The Converter service is built around the Aggregate Converter service and the Converter services. The aggregate converter tracks any Converter services. The Aggregate Converter dispatches conversion requests to the appropriate Converter service. The reified type is improved for the converter over blueprint. Arrays have now been defined as having a single type parameter: the component type. This approach made the conversion easier and more consistent. The API for both services consists of (Aggregate Converter extends Converter): <T> T convert(object s, ReifiedType<T> t); The ReifiedType is defined in Blueprin.However, the type is defined in the converter package. The Aggegrate Converter must support the following basic conversion algorithm: 1. if s == null, return null 2. Let sc = s.getclass 3. if sc isprimitive then sc = wrapper(sc) 4. If the target type isassignable from sc, then no conversion is necessary 5. Try all converters that indicate they can convert to the target type t in service.ranking order. The first converter that returns a non-null value succeeds the conversion 6. If the target type t == String.class, convert s to a string with tostring() 7. Try converting the following basic types to each other: -> Bool. Byte Char. Short Integ. Long Float Double BigInt. BigDc. Bool v 0,1 'F','T' 0,1 0,1 0,1 0.0, ,1.0 0,1 0,1 Byte v == 0? 0 : 1 Char. v == 0? 0 : 1 Short v == 0? 0 : 1 Integ. v == 0? 0 : 1 Long v == 0? 0 : 1 Float v == 0? 0 : 1 Double v == 0? 0 : 1 BigInt v == 0? 0 : 1 v v v v v v v v v v() v v v v v v v v v() v() v v v v v v v v() v() v() v v v v v v v() v() v() v() v v v v v v() v() v() v() v() v v v v v() v() v() v() v() v() v v v v() v() v() v() v() v() v() v v Copyright OSGi Alliance 2010

134 Command Line Interface Page 28 of 85 Draft November 12, > Bool. Byte Char. Short Integ. Long Float Double BigInt. BigDc. BigDec. v == 0? 0 : 1 String v.isempty? 0 : 1 v() v() v() v() v() v() v() v v TRUE, YES, ON are true (case insens.) others are false 1. v == the original value length == 1, then first character Short. parseshort Integer. parseint Long. parselong 2. v() takes the original value and checks if it fits in the target type 8. If sc is an array type, then convert to an array 1. Use the rules of collections to create a collection Float. parsefloat 2. Convert this to the appropriate array type, which can be a primitive array Double. parsedoub le new BigInteger( v) new BigDecimal (v) 9. If sc is assignable to Collection, convert it to a Collection<M>. M can be established through the ReifiedType t. 1. If the t is a type listed in the replacement types, replace it with the replacement type. This creates concrete classes for abstract classes and interfaces 2. Create a new instance of this type in l 3. if s is an array 1. convert each element to M and add it to l 2. return l 4. If sc isassignable from Collection 1. Convert each element to M and add it to I 2. return l 5. No conversion possible 10. If t isassignable from Dictionary 1. Create a Dictionary, if necessary using the replacement table 2. if sc not a Map or Dictionary then conversion fails 3. Convert s as a map or dictionary to the created dictionary while converting all keys and values. 11. If sc isassignable to Map 1. Create a Map, if necessary using the replacement table Copyright OSGi Alliance 2010

135 2. if sc not a Map or Dictionary then conversion fails Command Line Interface Page 29 of 85 Draft November 12, Convert s as a map or dictionary to the created dictionary while converting all keys and values. 12. If s is not a String object then conversion fails 13. if t is an Enum class, use the valueof method to convert s to an enum 14. Try the conversion from String to Locale, Pattern, and Properties. 15. if sc is a Class object, load the class from the string through the Bundle.loadClass method of the bundle that got the conversion service. 16. If t has a constructor that takes a String argument, use it to create a new object Any failures in any of the previous steps should result in a failure of the conversion, a null return. A Converter service must register with the the service property osgi.converter.classes. Its value is of type String+, reflecting the classes this converter can convert. For conversion, inheritance is not taken into account. When TSH needs to convert an object to a class or print an object of a specific class, it will call the registered Converter objects in the following order: filtered by matching class sorted by service.ranking, highest first sorted by service.id, lowest first 4.5 Formatter Service The Formatter service is built around the Aggregate Formatter service and the Formatter services. An Aggregate Formatter service can take an object, a level and a set of locales and return a string formatted version of this object. The Aggregate Formatter tracks any Formatter services. The Aggregate Formatter dispatches format requests to the appropriate Formatter service. The API for both services consists of (Aggregate Formatter extends Formatter): CharSequence format(object target, int level, Locale... locales) throws Exception - Format an object to a Char Sequence using the int parameter as a hint. The hint can be INSPECT, LINE, or PART. INSPECT - For an INSPECT, the output can be a multiline columnar output of any reasonable level. LINE - A LINE format must make the object look good in a table when different objects of the same type are printed below each other. PART - It is allowed to use multiple lines as long as the format works well in a table. A PART format is used to identify the object. E.g. a name or identifier. The PART format should be usable in the convert method when a CharSequence is the object to be converted. Copyright OSGi Alliance 2010

136 Command Line Interface Page 30 of 85 Draft November 12, 2010 INSPECT, LINE, and PART are ordered. That is, when printing an INSPECT, the next level should be to format an object with LINE, etc. A Formatter service must register with the the service property osgi.formatter.classes. Its value is of type String+, reflecting the classes this formatter can format. For conversion, inheritance is not taken into account. When one needs to convert an object to a class or print an object of a specific class, it will call the registered Converter objects in the following order: filtered by matching class sorted by service.ranking, highest first sorted by service.id, lowest first The following code shows a simple formatter for Bundle objects: import org.osgi.framework.*; import org.osgi.service.command.*; public class BundleConverter implements Formatter { BundleContext context; BundleConverter(BundleContext context) { this.context = context; } public CharSequence format(object o, int level, Locale.. locales) { if (!(o instanceof Bundle)) return null; Bundle b = (Bundle) o; StringBuffer sb = new StringBuffer(); switch (level) { case INSPECT: cols(sb, "Symbolic Name", b.getsymbolicname()); cols(sb, "Version", b.getheaders().get("bundle-version")); cols(sb, "State", b.getstate()); cols(sb, "Registered Services", escape.format(b.getregisteredservices(), level + 1, escape)); //... break; case PART: sb.append(b.getsymbolicname()).append(";").append( b.getheaders().get("bundle-version")); break; case LINE: sb.append(" ").append(b.getstate()).append(" ").append( b.getlocation()); break; } return sb; Copyright OSGi Alliance 2010

137 Command Line Interface Page 31 of 85 Draft November 12, 2010 } } void cols(stringbuffer sb, String label, Object value) { sb.append(label); for (int i = label.length(); i < 24; i++) sb.append(' '); sb.append(value).append('\n'); } 5 Javadoc Copyright OSGi Alliance 2010

138 Command Line Interface Page 32 of 85 Draft November 12, 2010 OSGi Javadoc 11/12/10 4:43 PM Package Summary org.osgi.servic e.command org.osgi.servic e.command.an notations org.osgi.servic e.converter org.osgi.servic e.converter.gen eric org.osgi.servic e.formatter org.osgi.servic e.threadio Command Package Version Command Annotations Package Version Converter Package Version Converter Package Version Formatter Package Version Thread IO Package Version Page Copyright OSGi Alliance 2010

139 Interface ArgumentList Package org.osgi.service.command Command Package Version 1.0. See: Description Interface Summary ArgumentList A Parameter List must be expanded to its constituents when used in a command line. 34 CommandProc essor CommandSess ion Function A Command Processor is a service that that can execute a script language. 35 A Command Session holds the executable state of a script engine as well as a Terminal that is connected to that session. A Function is a a block of code that can be executed with a set of arguments, it returns the result object of executing the script. MetaScope A Meta Scope defines the meta information of a set of commands grouped in a scope. 40 MetaScope.Met afunction MetaScope.Met afunction.meta Parameter Terminal Class Summary Terminal.Attrib ute Exception Summary ParsingExcepti on A Meta Function describes a scoped function. 42 A Meta Parameter describes parameter in a method. 44 The Terminal interface describes a minimal terminal that can easily be mapped to command line editing tools. An inner class to provide an enum for the attributes 65 An exception that can point at the location where the error occurred. 48 Package org.osgi.service.command Description Command Package Version 1.0. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.command; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.command; version="[1.0,1.1)" Page Page Page OSGi Javadoc -- 8/29/10 Page 33 of 85

140 Interface CommandProcessor Interface ArgumentList org.osgi.service.command All Superinterfaces: Collection<Object>, Iterable<Object>, List<Object> public interface ArgumentList extends List<Object> A Parameter List must be expanded to its constituents when used in a command line. It allows the following pattern: $ g = { grep -i (args $*) } $ g pattern file -> grep -i pattern file A ParameterList extends List, meaning that it can be manipulated as a list as well. OSGi Javadoc -- 8/29/10 Page 34 of 85

141 Interface CommandSession Interface CommandProcessor org.osgi.service.command public interface CommandProcessor A Command Processor is a service that that can execute a script language. A Command Processor is a factory for Command Session objects. The Command Session maintains execution state and holds the console and keyboard streams. A Command Processor must track any services that are registered with the COMMAND_SCOPE and COMMAND_FUNCTION properties. The functions listed in the COMMAND_FUNCTION property must be made available as functions in the script language. Version: $Id: b350e f8a4fc4da19afd25f560bb490ef4 $ ThreadSafe Field Summary String String String String COMMAND_DESCRIPTION A description of the command scope. COMMAND_FUNCTION A String+ of function names that may be called for this command provider. COMMAND_SCOPE The scope of commands provided by this service. COMMAND_SUMARY A summary of the command scope. Method Summary CommandSes sion CommandSes sion createsession(inputstream in, PrintStream out, PrintStream err, String encoding) Create a new command session associated with IO streams. createsession(terminal terminal) Create a new Command Session that is associated with a Terminal. Pag e Pag e Field Detail COMMAND_SCOPE public static final String COMMAND_SCOPE = "osgi.command.scope" The scope of commands provided by this service. This name can be used to distinguish between different command providers with the same function names. Commands can be executed as <scope>:<function>. COMMAND_FUNCTION public static final String COMMAND_FUNCTION = "osgi.command.function" A String+ of function names that may be called for this command provider. A name may end with a *, this wildcard will then be calculated from all public methods in this service. If this property is absent but the COMMAND_SCOPE is present then all methods in the service object are used as command. OSGi Javadoc -- 8/29/10 Page 35 of 85

142 Interface CommandSession COMMAND_DESCRIPTION public static final String COMMAND_DESCRIPTION = "osgi.command.description" A description of the command scope. This information is available through the MetaScope.getDescription() method. If this property is not set, it can come from the Description annotation or resources. COMMAND_SUMARY public static final String COMMAND_SUMARY = "osgi.command.summary" A summary of the command scope. This information is available through the MetaScope.getSummary() method. If this property is not set, it can come from the Description annotation or resources. Method Detail createsession CommandSession createsession(inputstream in, PrintStream out, PrintStream err, String encoding) Create a new command session associated with IO streams. The session is bound to the life cycle of the bundle getting this service. The session will be automatically closed when this bundle is stopped or the service is returned. The shell will provide any available commands to this session and can set additional variables that will be local to this session. Parameters: in - The value used for System.in. If null is passed, the implementation must create a valid Input Stream that always returns end of file. out - The stream used for System.out, must not be null err - The stream used for System.err, must not be null encoding - The character encoding to use, or null for the default Returns: A new session. createsession CommandSession createsession(terminal terminal) Create a new Command Session that is associated with a Terminal. A Terminal provides the common streams but adds extra capabilities for commands to control the screen. A session maintains this Terminal. Parameters: terminal - The terminal to use in this session Returns: A new sessions OSGi Javadoc -- 8/29/10 Page 36 of 85

143 Interface Function Interface CommandSession org.osgi.service.command public interface CommandSession A Command Session holds the executable state of a script engine as well as a Terminal that is connected to that session. Version: $Id: ce77a38eef120cfdc92234faa8cda8f5b0a73d92 $ NotThreadSafe Method Summary void Object Map<String,Object> Collection <MetaScope > Map<String,Object> Terminal URI close() Close this command session. execute(charsequence commandline) Execute a program in this session. getglobalvariables() Return the Map used to maintain the global variables. getmetascopes() Return the current list of Meta Scope objects. getsessionvariables() Return the modifiable Map used to store the local session variables. getterminal() Return the Terminal associated with this session. resolve(string path) Resolve a local name to a URI to the current working directory. Pag e Method Detail execute Object execute(charsequence commandline) throws Exception, ParsingException Execute a program in this session. Parameters: commandline - A Command line according to the script syntax. Returns: the result of the execution Throws: Exception - if something fails ParsingException - If the text contained a syntax error close void close() Close this command session. After the session is closed, it will throw IllegalStateException when it is used. OSGi Javadoc -- 8/29/10 Page 37 of 85

144 Interface Function getterminal Terminal getterminal() Return the Terminal associated with this session. The terminal is sometimes necessary to communicate directly to the end user. For example, a "less" or "more" command needs direct input from the keyboard to control the paging. Returns: Terminal used closest to the user, never null. getsessionvariables Map<String,Object> getsessionvariables() Return the modifiable Map used to store the local session variables. The returned Map can be modified to add/remove new variables, these changes are visible to the scripts running in this session. Returns: the map with all the variables getglobalvariables Map<String,Object> getglobalvariables() Return the Map used to maintain the global variables. The returned map can be modified to add/remove new variables, it is thread safe. Returns: the Map with all the global variables getmetascopes Collection<MetaScope> getmetascopes() Return the current list of Meta Scope objects. A scope represents a set of commands under a common name. The purpose of this information is to simplify command completion and providing extensive help about commands. If an implementation supports annotations it can use the annotations to provide extra information. Returns: A unmodifiable collection of MetaScope objects. resolve URI resolve(string path) Resolve a local name to a URI to the current working directory. If the name is absolute, an absolute URI is returned. Parameters: path - A relative or absolute URI Returns: a URI that is the original when it was absolute and resolved against the $CWD variable if relative. OSGi Javadoc -- 8/29/10 Page 38 of 85

145 Interface MetaScope Interface Function org.osgi.service.command public interface Function A Function is a a block of code that can be executed with a set of arguments, it returns the result object of executing the script. The purpose of the Function is to be injected in commands. Many commands require the possibility to execute closures or other commands. For example, a foreach command requires a block for execution: void foreach( Iterable?> collection, Function block ) { for ( Object o : collection ) block.execute( Arrays.asList(o)); Version: $Id: c047b4c99d99eff571349bdb3a9a1a463408bf86 $ ThreadSafe Method Summary Object execute(commandsession session, List<?> arguments) Execute this function and return the result. Pag e 39 Method Detail execute Object execute(commandsession session, List<?> arguments) throws Exception Execute this function and return the result. Parameters: session - The session in which to execute this function arguments - The list of arguments. This list will not be modified. Returns: the result from the execution. Throws: Exception - if anything goes wrong OSGi Javadoc -- 8/29/10 Page 39 of 85

146 Interface MetaScope.MetaFunction Interface MetaScope org.osgi.service.command public interface MetaScope A Meta Scope defines the meta information of a set of commands grouped in a scope. The information about the scopes can be obtained from CommandSession.getMetaScopes(). If annotations are present, the information is augmented with information. Version: $Id: af55c20f0fe35b4955a9befc1d5d6e139b7ffa50 $ ThreadSafe Nested Class Summary static interface MetaScope.MetaFunction A Meta Function describes a scoped function. Pag e 42 Method Summary String Collection <? extends MetaScope. MetaFuncti on> String String getdescription() Return a description of this scope, if present. getmetafunctions() Return an unmodifiable list of Meta Function objects. 41 getname() Return the name of this scope. getsummary() Return the summary. Pag e Method Detail getname String getname() Return the name of this scope. Returns: Name of the scope, always non-null. getdescription String getdescription() Return a description of this scope, if present. The description is derived from annotation or from localized resources. Returns: A description or null OSGi Javadoc -- 8/29/10 Page 40 of 85

147 Interface MetaScope.MetaFunction getsummary String getsummary() Return the summary. The summary is derived from annotation or from localized resources. Returns: A summary or null getmetafunctions Collection<? extends MetaScope.MetaFunction> getmetafunctions() Return an unmodifiable list of Meta Function objects. This list is a snapshot of the current state. Each member of the returned list describes an existing function that can be called in this scope. Returns: an unmodifiable list of Meta Function objects. OSGi Javadoc -- 8/29/10 Page 41 of 85

148 Interface MetaScope.MetaFunction.MetaParameter Interface MetaScope.MetaFunction org.osgi.service.command Enclosing class: MetaScope public static interface MetaScope.MetaFunction A Meta Function describes a scoped function. The information is derived from annotation on the method Nested Class Summary static interface MetaScope.MetaFunction.MetaParameter A Meta Parameter describes parameter in a method. Method Summary String Collection <? extends MetaScope. MetaFuncti on.metapar ameter> String String boolean getdescription() Return a description of this function, if present. getmetaparameters() Return the Meta Parameter objects of this Meta Function. getname() Return the name of this function. getsummary() Return a summary of this function, if present. isvarargs() Answer if this is mapped to a vararg method. Pag e 44 Pag e Method Detail getname String getname() Return the name of this function. This is normally the corresponding method name. From the command line, a simpler form of the name can be used. Returns: Name of the function, always non-null. getdescription String getdescription() Return a description of this function, if present. This information comes from annotation or resources. Returns: A description or null OSGi Javadoc -- 8/29/10 Page 42 of 85

149 Interface MetaScope.MetaFunction.MetaParameter getsummary String getsummary() Return a summary of this function, if present. This information comes from annotation or resources. Returns: A summary or null getmetaparameters Collection<? extends MetaScope.MetaFunction.MetaParameter> getmetaparameters() Return the Meta Parameter objects of this Meta Function. Each parameter in the associated method has a MetaParameter object associated with it. This object derives its information from annotation as well as the method and its parameter types information. Every parameter has a MetaParameter object, regardless if it has annotation. Returns: The Meta Parameter objects, never null isvarargs boolean isvarargs() Answer if this is mapped to a vararg method. A vararg method can be used to fill out the last parameters of a function with remaining arguments. Returns: true if this is for a vararg method, otherwise false OSGi Javadoc -- 8/29/10 Page 43 of 85

150 Class ParsingException Interface MetaScope.MetaFunction.MetaParameter org.osgi.service.command Enclosing class: MetaScope.MetaFunction public static interface MetaScope.MetaFunction.MetaParameter A Meta Parameter describes parameter in a method. Each parameter in a method has a corresponding Meta Parameter. Method Summary String String String[] String int String ReifiedTyp e<?> boolean boolean absent() The value to use when a named parameter has not been used or when an unnamed parameter can accept a default. flag() The value to use for a flag when it is used in the command line. getaliases() List the name of aliases for this named parameter. getdescription() Return a description of this parameter, if present. getindex() Answer the index of the parameter in the method. getsummary() Return a summary of this parameter, if present. gettype() Return the Java type of the parameter. isflag() Answer if this parameter is a flag. ismandatory() Answer if this Meta Parameter has an absent value. boolean isnamed() 47 boolean boolean isoption() Answer if this parameter is an option. isrepeat() Answer if this option is can be used multiple times. boolean issession() 46 Pag e Method Detail getindex int getindex() Answer the index of the parameter in the method. Returns: The index of the parameter getdescription String getdescription() OSGi Javadoc -- 8/29/10 Page 44 of 85

151 Class ParsingException Return a description of this parameter, if present. This information comes from annotation or resources. Returns: A description or null getsummary String getsummary() Return a summary of this parameter, if present. This information comes from annotation or resources. Returns: A summary or null getaliases String[] getaliases() List the name of aliases for this named parameter. An alias must start with a minus sign ('-' -) and must not be '--'. For example: {"-f", "--file"} If the list of aliases can be empty, in that case this must be an unnamed parameter. Unnamed parameters can provide a default as well as a description for a parameter. Returns: Array of aliases, never null. gettype ReifiedType<?> gettype() Return the Java type of the parameter. This is a Reified Type that can be used in the conversion model. Returns: the Refied Type that describes the parameter's type. absent String absent() The value to use when a named parameter has not been used or when an unnamed parameter can accept a default. If this method returns Parameter.NOT_SET then there is no default set. In that case, an unnamed parameter or an option is mandatory. Returns: The value to use when the parameter is not used in the command line, can be null or Parameter.NOT_SET. flag String flag() The value to use for a flag when it is used in the command line. This method is Parameter.NOT_SET for an option. OSGi Javadoc -- 8/29/10 Page 45 of 85

152 Class ParsingException Returns: the parameter value for a flag. isoption boolean isoption() Answer if this parameter is an option. An option has NOT_SET for absent and at least one alias. It therefore requires a For an unnamed parameter or a parameter without annotation this method always returns false. Returns: true if this is an option, false otherwise isflag boolean isflag() Answer if this parameter is a flag. A flag has not NOT_SET for absent and at least one alias. It therefore requires a For an unnamed parameter or a parameter without annotation this method always returns false. Returns: true if this is a flag, false otherwise isrepeat boolean isrepeat() Answer if this option is can be used multiple times. If so, multiple arguments for the option are collection in a collection and converted to the parameter type, which must then be an array or collection. This parameter must be an option for isrepeat to be true. For an unnamed parameter or a parameter without a Parameter annotation this method always returns false. Returns: true if this is an option and the repeat flag is set in the Parameter annotation. Otherwise false ismandatory boolean ismandatory() Answer if this Meta Parameter has an absent value. If so, this parameter is not mandatory. If the absent value is NOT_SET, return false. Both named and unnamed parameters can be mandatory/optional. For a parameter without annotation this method always returns false. Returns: true if the absent value is not equal to Parameter.NOT_SET, otherwise false. issession boolean issession() Returns: true if this parameter expects a Command Session, false otherwise. OSGi Javadoc -- 8/29/10 Page 46 of 85

153 Class ParsingException isnamed boolean isnamed() Returns: true if there is at least one alias, false otherwise. OSGi Javadoc -- 8/29/10 Page 47 of 85

154 Interface Terminal Class ParsingException org.osgi.service.command java.lang.object java.lang.throwable java.lang.exception java.lang.runtimeexception org.osgi.service.command.parsingexception All Implemented Interfaces: Serializable public class ParsingException extends RuntimeException An exception that can point at the location where the error occurred. Constructor Summary ParsingException(String message, int line, int column) Constructor to create a syntax exception. Method Summary int int getcolumn() Get the column number where the parser failed. getline() Get the line number where the parser failed. Pag e 48 Pag e Constructor Detail ParsingException public ParsingException(String message, int line, int column) Constructor to create a syntax exception. Parameters: message - A human readable message line - The line number at which the parser failed to recognize the text column - The column at which the parser failed to recognize the text Method Detail getline public int getline() Get the line number where the parser failed. Returns: The line # where the parser failed. OSGi Javadoc -- 8/29/10 Page 48 of 85

155 Interface Terminal getcolumn public int getcolumn() Get the column number where the parser failed. Returns: The column # where the parser failed. OSGi Javadoc -- 8/29/10 Page 49 of 85

156 Class Terminal.Attribute Interface Terminal org.osgi.service.command public interface Terminal The Terminal interface describes a minimal terminal that can easily be mapped to command line editing tools. A Terminal is associated with an Input Stream and an Output Stream. The Input Stream represents the keyboard and the Output Stream the screen. A terminal does not block the input, each character is returned as it is typed, no buffering or line editing takes place, characters are also not echoed. However, the Input Stream is not restricted to bytes only, it can also return translated key strokes. Integers from 1000 are used for those. Not all keys have to be supported by an implementation. A number of functions is provided to move the cursor and erase characters/lines/screens. Any text outputed to the Output Stream is immediately added to the cursor position, which is then moved forwards. The control characters (LF,CR,TAB,BS) perform their normal actions. However lines do not wrap. Text typed that is longer than the window will not be visible, it is the responsibility of the sender to ensure this does not happen. A screen is considered to be getheight() lines that each have getwidth() characters. For cursor positioning, the screen is assumed to be starting at 0,0 and increases its position from left to right and from top to bottom. Positioning outside the screen bounds is undefined. Nested Class Summary static class Field Summary Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.Attribute An inner class to provide an enum for the attributes BACK_BLACK Black BACK_BLUE Blue BACK_CYAN Cyan BACK_DEFAULT Default background color. BACK_GREEN Green BACK_MAGENTA Magenta BACK_NONE No Color, transparent. BACK_RED Red BACK_WHITE White BACK_YELLOW Yellow Terminal.A ttribute BOLD Bolden the text. Pag e 65 Pag e int int int int BREAK Break key CONTROL_START Start point of control characters. CURSOR_BACKWARD Cursors backward key. CURSOR_DOWN Cursor down key OSGi Javadoc -- 8/29/10 Page 50 of 85

157 Class Terminal.Attribute int int int int int int int int int int int int int int int int Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute Terminal.A ttribute int CURSOR_FORWARD Cursors forward key. CURSOR_UP Cursor up key DELETE Delete key END F1 F10 F11 F12 F2 F3 F4 F5 F6 F7 F8 F9 End key FORE_BLACK Black FORE_BLUE Blue FORE_CYAN Cyan Function key 1 Function key 10 Function key 11 Function key 12 Function key 2 Function key 3 Function key 4 Function key 5 Function key 6 Function key 7 Function key 8 Function key 9 FORE_DEFAULT Default foreground color. FORE_GREEN Green FORE_MAGENTA Magenta FORE_NONE No Color, transparent. FORE_RED Red FORE_WHITE White FORE_YELLOW Yellow FUNCTION_START Helper OSGi Javadoc -- 8/29/10 Page 51 of 85

158 Class Terminal.Attribute int int int int long long long Terminal.A ttribute int long long long long long Terminal.A ttribute HOME Home key INSERT Insert key PAGE_DOWN Page down key PAGE_UP Page up key REPORTS_CURSOR_POS Value for getcapabilities(), if set this Terminal can report the cursor position. REPORTS_SIZE Value for getcapabilities(), if set this Terminal can report the current size, see getheight() and getwidth(). REPORTS_SIZE_CHANGES Value for getcapabilities(), if set this Terminal sends a control code when the terminal changes size. REVERSED Reverse the text. SIZE_CHANGE The window size has changed. SUPPORTS_ATTRIBUTES Value for getcapabilities(), if set this Terminal supports attributes. SUPPORTS_BIDIRECTIONAL_SCRIPTS Value for getcapabilities(), if set this Terminal will handle bidirectional scripts. SUPPORTS_CURSOR_POS Value for getcapabilities(), if set this Terminal supports setting the cursor position. SUPPORTS_LATIN_1_SUPPLEMENT Value for getcapabilities(), if set this Terminal supports the LATIN_1 supplement. SUPPORTS_UNICODE Value for getcapabilities(), if set this Terminal supports the full UNICODE set. UNDERLINE Underline the text Method Summary Terminal.A ttribute[] void void void void void long PrintWrite r int attributes(terminal.attribute... attr) Set the attributes of the text to outputed next. backward() Move the cursor backward. clear() Clear the complete screen and position the cursor at 0,0. down() Move the cursor down one line, this must not cause a scroll if the cursors moves off the screen. eraseendofline() Leave the cursor where it is but clear the remainder of the line. forward() Move the cursor forward. getcapabilities() Answer the capabilities of this terminal. geterr() Return the associated standard error stream. getheight() Return the actual height of the screen. Pag e OSGi Javadoc -- 8/29/10 Page 52 of 85

159 Class Terminal.Attribute int PrintWrite r int[] int getin() Get a character from the input. getout() Return the associated standard output stream. getposition() Return the current cursor position. getwidth() Return the actual width of the screen. boolean position(int x) Position the cursor x position on the screen. boolean position(int x, int y) Position the cursor on the screen. String readline() Read a complete line from the input. void up() Move the cursor up one line, this must not cause a scroll if the cursor moves off the screen Field Detail CONTROL_START public static final int CONTROL_START = Start point of control characters. CURSOR_UP public static final int CURSOR_UP = Cursor up key CURSOR_DOWN public static final int CURSOR_DOWN = Cursor down key. CURSOR_FORWARD public static final int CURSOR_FORWARD = Cursors forward key. Usually right. CURSOR_BACKWARD public static final int CURSOR_BACKWARD = Cursors backward key. Usually left. OSGi Javadoc -- 8/29/10 Page 53 of 85

160 Class Terminal.Attribute PAGE_UP public static final int PAGE_UP = Page up key PAGE_DOWN public static final int PAGE_DOWN = Page down key HOME public static final int HOME = Home key END public static final int END = End key INSERT public static final int INSERT = Insert key DELETE public static final int DELETE = Delete key BREAK public static final int BREAK = Break key SIZE_CHANGE public static final int SIZE_CHANGE = The window size has changed. OSGi Javadoc -- 8/29/10 Page 54 of 85

161 Class Terminal.Attribute FUNCTION_START public static final int FUNCTION_START = Helper F1 public static final int F1 = Function key 1 F2 public static final int F2 = Function key 2 F3 public static final int F3 = Function key 3 F4 public static final int F4 = Function key 4 F5 public static final int F5 = Function key 5 F6 public static final int F6 = Function key 6 F7 public static final int F7 = Function key 7 OSGi Javadoc -- 8/29/10 Page 55 of 85

162 Class Terminal.Attribute F8 public static final int F8 = Function key 8 F9 public static final int F9 = Function key 9 F10 public static final int F10 = Function key 10 F11 public static final int F11 = Function key 11 F12 public static final int F12 = Function key 12 UNDERLINE public static final Terminal.Attribute UNDERLINE Underline the text. BOLD public static final Terminal.Attribute BOLD Bolden the text. REVERSED public static final Terminal.Attribute REVERSED Reverse the text. OSGi Javadoc -- 8/29/10 Page 56 of 85

163 Class Terminal.Attribute FORE_DEFAULT public static final Terminal.Attribute FORE_DEFAULT Default foreground color. FORE_NONE public static final Terminal.Attribute FORE_NONE No Color, transparent. FORE_BLACK public static final Terminal.Attribute FORE_BLACK Black FORE_GREEN public static final Terminal.Attribute FORE_GREEN Green FORE_YELLOW public static final Terminal.Attribute FORE_YELLOW Yellow FORE_MAGENTA public static final Terminal.Attribute FORE_MAGENTA Magenta FORE_CYAN public static final Terminal.Attribute FORE_CYAN Cyan FORE_BLUE public static final Terminal.Attribute FORE_BLUE Blue OSGi Javadoc -- 8/29/10 Page 57 of 85

164 Class Terminal.Attribute FORE_RED public static final Terminal.Attribute FORE_RED Red FORE_WHITE public static final Terminal.Attribute FORE_WHITE White BACK_DEFAULT public static final Terminal.Attribute BACK_DEFAULT Default background color. BACK_NONE public static final Terminal.Attribute BACK_NONE No Color, transparent. BACK_BLACK public static final Terminal.Attribute BACK_BLACK Black BACK_GREEN public static final Terminal.Attribute BACK_GREEN Green BACK_YELLOW public static final Terminal.Attribute BACK_YELLOW Yellow BACK_MAGENTA public static final Terminal.Attribute BACK_MAGENTA Magenta OSGi Javadoc -- 8/29/10 Page 58 of 85

165 Class Terminal.Attribute BACK_CYAN public static final Terminal.Attribute BACK_CYAN Cyan BACK_BLUE public static final Terminal.Attribute BACK_BLUE Blue BACK_RED public static final Terminal.Attribute BACK_RED Red BACK_WHITE public static final Terminal.Attribute BACK_WHITE White REPORTS_CURSOR_POS public static final long REPORTS_CURSOR_POS = 1L Value for getcapabilities(), if set this Terminal can report the cursor position. See position(int, int) REPORTS_SIZE_CHANGES public static final long REPORTS_SIZE_CHANGES = 2L Value for getcapabilities(), if set this Terminal sends a control code when the terminal changes size. See SIZE_CHANGE. REPORTS_SIZE public static final long REPORTS_SIZE = 4L Value for getcapabilities(), if set this Terminal can report the current size, see getheight() and getwidth(). SUPPORTS_BIDIRECTIONAL_SCRIPTS public static final long SUPPORTS_BIDIRECTIONAL_SCRIPTS = 256L OSGi Javadoc -- 8/29/10 Page 59 of 85

166 Class Terminal.Attribute Value for getcapabilities(), if set this Terminal will handle bidirectional scripts. If supported, text and cursor movements must be automatically reordered to match the visualization. This will allow users to just send Unicode strings where text is in increasing memory order. Any reordering is only done on the display. SUPPORTS_ATTRIBUTES public static final long SUPPORTS_ATTRIBUTES = 1024L Value for getcapabilities(), if set this Terminal supports attributes. If not set, attributes(attribute...) will always return null. SUPPORTS_CURSOR_POS public static final long SUPPORTS_CURSOR_POS = 16384L Value for getcapabilities(), if set this Terminal supports setting the cursor position. If not set, position(int, int) will always return false and not set the cursor. SUPPORTS_LATIN_1_SUPPLEMENT public static final long SUPPORTS_LATIN_1_SUPPLEMENT = 65536L Value for getcapabilities(), if set this Terminal supports the LATIN_1 supplement. These are the UNICODE 80-FF codes. A Terminal must minimally support US-ASCII. SUPPORTS_UNICODE public static final long SUPPORTS_UNICODE = L Value for getcapabilities(), if set this Terminal supports the full UNICODE set. This does not imply Bidirectional script handling. A Terminal must minimally support US-ASCII. Method Detail getin int getin() throws Exception Get a character from the input. Characters less than 0x10000 are Unicode characters, if more it is a control code defined by the constants in this class. Returns: the current Input Stream. Throws: Exception - When character cannot be read readline String readline() throws Exception OSGi Javadoc -- 8/29/10 Page 60 of 85

167 Class Terminal.Attribute Read a complete line from the input. The result will not contain any command codes, just text. Implementers can allow line editing and history handling. The string must not contain the LF or CR at the end. Returns: a new line Throws: Exception getout PrintWriter getout() Return the associated standard output stream. Returns: the associated standard output stream geterr PrintWriter geterr() Return the associated standard error stream. Returns: the associated standard error stream clear void clear() throws Exception Clear the complete screen and position the cursor at 0,0. Throws: Exception - when the method fails eraseendofline void eraseendofline() throws Exception Leave the cursor where it is but clear the remainder of the line. Throws: Exception - when the method fails up void up() throws Exception Move the cursor up one line, this must not cause a scroll if the cursor moves off the screen. OSGi Javadoc -- 8/29/10 Page 61 of 85

168 Class Terminal.Attribute Throws: Exception - when the method fails down void down() throws Exception Move the cursor down one line, this must not cause a scroll if the cursors moves off the screen. Throws: Exception - when the method fails backward void backward() throws Exception Move the cursor backward. Must not wrap to previous line. Throws: Exception - when the method fails forward void forward() throws Exception Move the cursor forward. Must not wrap to next line if the cursor becomes higher than the width. Throws: Exception - when the method fails getwidth int getwidth() throws Exception Return the actual width of the screen. Some screens can change their size and this method must return the actual width if possible. If the width cannot be established a -1 must be returned. If the size changes and the terminal supports reporting these events a SIZE_CHANGE key must be returned. Returns: the width of the screen or -1. Throws: Exception - when the method fails getheight int getheight() throws Exception Return the actual height of the screen. Some screens can change their size and this method must return the actual height if possible. If the width cannot be established a -1 must be returned. If the size changes and the terminal supports reporting these events a SIZE_CHANGE key must be returned. OSGi Javadoc -- 8/29/10 Page 62 of 85

169 Class Terminal.Attribute Returns: the height of the screen or -1. Throws: Exception - when the method fails getposition int[] getposition() throws Exception Return the current cursor position. The position is returned as an array of 2 elements. The first element is the x position and the second elements is the y position. Both are zero based. Returns: the current position or null if it is not possible to establish the cursor position. Throws: Exception - when the method fails position boolean position(int x, int y) throws IllegalArgumentException, Exception Position the cursor on the screen. Positioning starts at 0,0 and the maximum value is given by getwidth(), getheight(). The visible cursor is moved to this position and text insertion will continue from that position. Parameters: x - The x position, must be from 0-width y - The y position, must be from 0-height Returns: true if the position could be set, otherwise false Throws: IllegalArgumentException - when x or y is not in range Exception - when this method fails position boolean position(int x) throws IllegalArgumentException, Exception Position the cursor x position on the screen. Is the same as position(x,y), where y represents the current line on the screen. Parameters: x - The x position, must be from 0-width Returns: true if the position could be set, otherwise false Throws: IllegalArgumentException - when x or y is not in range Exception - when this method fails attributes Terminal.Attribute[] attributes(terminal.attribute... attr) throws Exception OSGi Javadoc -- 8/29/10 Page 63 of 85

170 Class Terminal.Attribute Set the attributes of the text to outputed next. The method returns the current settings, which can be used to restore the display to the previous state. These current settings are stream based and not associated with the position of the cursor. Attributes must be completely specified, they do not inherit from the current display. If attributes are specified multiple times, the last one wins. Parameters: attr - A number of attributes describing the output Returns: The previous state of attributes or null if attributes are not supported. Throws: Exception - when this method fails getcapabilities long getcapabilities() Answer the capabilities of this terminal. The following capabilities can be returned: Returns: the bitmap of capabilities OSGi Javadoc -- 8/29/10 Page 64 of 85

171 Package org.osgi.service.command.annotations Class Terminal.Attribute org.osgi.service.command java.lang.object org.osgi.service.command.terminal.attribute Enclosing class: Terminal public static class Terminal.Attribute extends Object An inner class to provide an enum for the attributes Method Summary String tostring() 65 Pag e Method Detail tostring public String tostring() Overrides: tostring in class Object OSGi Javadoc -- 8/29/10 Page 65 of 85

172 Annotation Type Description Package org.osgi.service.command.annotations Command Annotations Package Version 1.0. See: Description Annotation Types Summary Description Provide a description for this element. 67 Parameter A Parameter provides the information to treat a method parameter as a flag or option. 68 Package org.osgi.service.command.annotations Description Command Annotations Package Version 1.0. The purpose of this package is to provide access to the annotations for the command shell. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.command.annotations; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.command.annotations; version="[1.0,1.1)" Page OSGi Javadoc -- 8/29/10 Page 66 of 85

173 Annotation Type Parameter Annotation Type ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER }) Description Provide a description for this element. This is a generic annotation that can be used describe types, methods, and parameters. The information in this annotation can end up in the Command Descriptor. The usage of the Description is like: Version: $Id: c97161ad7adc294d6eb706e182afb0d547d18538 $ Required Element Summary String summary 67 String value The descriptive text. Pag e 67 Element Detail value public abstract String value The descriptive text. Returns: the descriptive text summary public abstract String summary Default: "" Returns: the summary or null OSGi Javadoc -- 8/29/10 Page 67 of 85

174 Annotation Type Parameter Annotation Type Parameter A Parameter provides the information to treat a method parameter as a flag or option. Options and flags always start with a minus sign ('-, -) in the command line. An option always is followed by a value while a flag goes without a value. The distinction is made with the flag() method. If this method returns NOT_SET then this Parameter describes an option, otherwise it is a flag because a value is provided when the flag is used. If the same name aliases are used in other flags or options than the first one in the parameter declaration wins. Flags and options must be the first parameters in the method, it is not possible to intersperse the flags and options with parameters that have none. All remaining parameters without a Parameter description are unnamed. Version: $Id: 9e89771bf12143b1d532b6c09bcab8669d9cd26b $ Field Summary String String NOT_SET Magic value to provide a default for absent() and flag() to indicate it is not set. NULL Null value Required Element Summary String String[] String boolean absent The value of the parameter if its name is not present on the command line. alias Parameter name and aliases. flag The value if the flag or option is used in the command line. repeat Set if this parameter can be repeated multiple times. Pag e Pag e Field Detail NOT_SET public static final String NOT_SET = "be3831f6ddfaa48efe1c0aba9e81c6251bf0f0ca" Magic value to provide a default for absent() and flag() to indicate it is not set. NULL public static final String NULL = "be3831f6ddfaa48efe1c0aba9e81c6251bf0f0cb" Null value OSGi Javadoc -- 8/29/10 Page 68 of 85

175 Annotation Type Parameter Element Detail alias public abstract String[] alias Parameter name and aliases. The shell will only be able to recognize names that start with a hyphen ('-', '-'), however, other names are allowed. If the list of aliases is empty, For example, to support the options -f/--files, return {"-f", "--files"}. If the alias contains an empty array then the Parameter can be provided by the session because it is a built in value like the Command Session object or the Terminal. Default: {} Returns: parameter names. flag public abstract String flag The value if the flag or option is used in the command line. If this returns NOT_SET then this is an option and the value after the alias must be used. This value mist always be set for a flag. Default: "be3831f6ddfaa48efe1c0aba9e81c6251bf0f0ca" Returns: The value to use when one of the flag names is present in the command line. absent public abstract String absent The value of the parameter if its name is not present on the command line. This value is effectively the default value for the parameter. If this method returns NOT_SET then this option must be specified. Default: "be3831f6ddfaa48efe1c0aba9e81c6251bf0f0ca" Returns: default value of the parameter if its name is not present on the command line. repeat public abstract boolean repeat Set if this parameter can be repeated multiple times. This only makes sense for options, not for flags. For an option, the collected parameters will be aggregated in a Collection. Default: false OSGi Javadoc -- 8/29/10 Page 69 of 85

176 Package org.osgi.service.converter Package org.osgi.service.converter Converter Package Version 1.0. See: Description Interface Summary AggregateConv erter The Aggregate Converter service aggregates the Converter services present in the service registry. Converter A Converter service can convert an object to another type. 72 Page 71 Class Summary ReifiedType Provides access to a concrete type and its optional generic type parameters without relying on the Java 5 (and later) Type classes. Page 73 Package org.osgi.service.converter Description Converter Package Version 1.0. The purpose of this package is to provide access to a Converter service. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.converter; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.converter; version="[1.0,1.1)" OSGi Javadoc -- 8/30/10 Page 70 of 85

177 Interface AggregateConverter Interface AggregateConverter org.osgi.service.converter All Superinterfaces: Converter public interface AggregateConverter extends Converter The Aggregate Converter service aggregates the Converter services present in the service registry. That is, a Converter service provides the converting facility for one or more types, an Aggregate Converter service provides converting for any object by using the Converter services present in the service registry, as well as providing a number of basic type conversions. When called, an Aggregate Converter must use the Converter.OSGI_CONVERTER_TYPE property of the Converter services to determine which service to use. Finding the right converter must follow the following rules: The goal of the type conversion is to convert a source object s with type S to a target type T<P1..Pn>. The Aggregator Converter must attempt to find the first Converter service (in service.ranking order) that successfully performs this conversion. If no capable Converter service can be found, the Aggregator Converter service must provide a number of basic conversions as described in the specification. These conversions handle arrays, collections, and many built-in types, see the specification. An Aggregate Formatter must not register with a Converter.OSGI_CONVERTER_TYPE service property. The Aggregate Converter service uses the same signature as the Converter Service, this interface is therefore a marker interface to simplify getting access to the Aggregator service. Version: $Id: f4f07c eb17e e7a63fabfb27314 $ ThreadSafe Fields inherited from interface org.osgi.service.converter.converter OSGI_CONVERTER_TYPE Methods inherited from interface org.osgi.service.converter.converter convert OSGi Javadoc -- 8/30/10 Page 71 of 85

178 Interface Converter Interface Converter org.osgi.service.converter All Known Subinterfaces: AggregateConverter public interface Converter A Converter service can convert an object to another type. For example the command shell can use this service to coerce the source type (in this case often a string) to a destination type, for example a parameter in a method. However, converters are general converters, they must be able to handle any source type though it is not required that they can actually perform the conversion. A Converter service must register with the OSGI_CONVERTER_TYPE service property. This property specifies the names of the class and interfaces this Converter service can convert to one or more target types. Multiple Converter services can provide conversion of the same class/interface. An AggregateConverter must use these services in service ranking order, the first Converter service that can convert the source object to the target type will be chosen. Due to different class space the target type can be a recognized class name but still fail because the converter belongs to another class space. Converter services must therefore be careful to check if they are in the same class space as the target type. Version: $Id: 327c478c4cfc4fed1b61ba8a4d $ Field Summary String OSGI_CONVERTER_TYPE Names of classes/interfaces that this Converter service has conversions for. Method Summary T convert(object sourceobject, ReifiedType<T> targettype) Convert an object to the desired type. Pag e 72 Pag e 72 Field Detail OSGI_CONVERTER_TYPE public static final String OSGI_CONVERTER_TYPE = "osgi.converter.type" Names of classes/interfaces that this Converter service has conversions for. It is a service property that is a String+. That is, a string, or an array/collection of strings. Method Detail convert T convert(object sourceobject, ReifiedType<T> targettype) Convert an object to the desired type. Return null if the conversion can not be done. Otherwise return an object that extends the desired type or implements it. Type Parameters: T - The raw type of the desired result object Parameters: sourceobject - The object that must be converted targettype - The type that the returned object can be assigned to Returns: An object that can be assigned to the desired type or null if it could not be converted. OSGi Javadoc -- 8/30/10 Page 72 of 85

179 Class ReifiedType Class ReifiedType org.osgi.service.converter java.lang.object org.osgi.service.converter.reifiedtype Type Parameters: T - The raw type. Direct Known Subclasses: GenericType public class ReifiedType extends Object Provides access to a concrete type and its optional generic type parameters without relying on the Java 5 (and later) Type classes. Java 5 and later support generic types. These types consist of a raw class with type parameters, e.g. T<P1,...,Pn>. This class models such a Type class but ensures that the type is reified. Reification means that the Type graph associated with a Java 5 Type instance is traversed until the type becomes a concrete class. This class is available with the getrawclass() method. The optional type parameters are recursively represented as Reified Types. In Java 1.4, a class has by definition no type parameters. This class implementation provides the Reified Type for Java 1.4 by making the raw class the Java 1.4 class and using a Reified Type based on the Object class for any requested type parameter. Implementations can subclass this class and provide access to the generic type parameter graph for conversion. Such a subclass must reify the different Java 5 Type instances into the reified form. That is, a form where the raw Class is available with its optional type parameters as Reified Types. For example: class Foo { Map? extends T>> map =...; } The Type graph for map will be quite complex due to the variable T Version: $Id: 7fff2ea924548b4cb4e275065f0a142f8d8467eb $ Immutable Constructor Summary ReifiedType(Class<T> clazz) Create a Reified Type for a raw Java class without any generic type parameters. Method Summary ReifiedTyp e<?> Class<T> int getactualtypeargument(int i) Return a type parameter for this type. getrawclass() Return the raw class represented by this type. size() Return the number of type parameters for this type. Pag e 73 Pag e Constructor Detail ReifiedType public ReifiedType(Class<T> clazz) OSGi Javadoc -- 8/30/10 Page 73 of 85

180 Class ReifiedType Create a Reified Type for a raw Java class without any generic type parameters. Subclasses can provide the optional generic type parameter information. Without subclassing, this instance has no type parameters. Parameters: clazz - The raw class of the Reified Type. Method Detail getrawclass public Class<T> getrawclass() Return the raw class represented by this type. The raw class represents the concrete class that is associated with a type declaration. This class could have been deduced from the generics type parameter graph of the declaration. For example, in the following example: Map<String,? extends Metadata> In this example, the raw class is the Map interface. Returns: The raw class represented by this type. getactualtypeargument public ReifiedType<?> getactualtypeargument(int i) Return a type parameter for this type. The type parameter refers to a parameter in a generic type declaration given by the zero-based index i. For example, in the following example: Map<String,? extends Metadata> type parameter 0 is String, and type parameter 1 is Metadata. This implementation returns a Reified Type that has Object as class. Any object is assignable to Object and therefore no conversion is then necessary. This is compatible with versions of Java language prior to Java 5. This method should be overridden by a subclass that provides access to the generic type parameter information for Java 5 and later. Parameters: i - The zero-based index of the requested type parameter. Returns: The ReifiedType for the generic type parameter at the specified index. size public int size() Return the number of type parameters for this type. This implementation returns 0. This method should be overridden by a subclass that provides access to the generic type parameter information for Java 5 and later. Returns: The number of type parameters for this type. OSGi Javadoc -- 8/30/10 Page 74 of 85

181 Package org.osgi.service.formatter Package org.osgi.service.converter.generic Converter Package Version 1.0. See: Description Class Summary GenericType A GenericType provides a concrete implementation of a ReifiedType that bases its decisions on the generic runtime information in the Java 5 and later VMs. Page 76 Package org.osgi.service.converter.generic Description Converter Package Version 1.0. The purpose of this package is to provide access to a Converter service. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.converter.generic; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.converter.generic; version="[1.0,1.1)" OSGi Javadoc -- 8/30/10 Page 75 of 85

182 Interface AggregateFormatter Class GenericType org.osgi.service.converter.generic java.lang.object org.osgi.service.converter.reifiedtype<t> org.osgi.service.converter.generic.generictype Type Parameters: T - The type argument for this GenericType public class GenericType extends ReifiedType<T> A GenericType provides a concrete implementation of a ReifiedType that bases its decisions on the generic runtime information in the Java 5 and later VMs. It is instantiated with a Type argument, the implementation will then analyze the Type structure and collapse all variables, wildcards, and arrays to a consistent model of a raw class and 0 or more type GenericType type arguments. Though Java erases much of the generic type information, method arguments, return types of methods, field types, and super class/interface implements definitions retain their generic information. In the following example: Collection<String> c; The field c contains a ParameterizedType that has a raw type that is Collection.class and a type argument at index 0 that is String.class. The generic type information can be extremely useful for type conversions because it maintains the constraints specified by the programmer. For example, if a method returns Collection<String> than it is important that the type conversion actually places strings in the collections. The converter service provides a ReifiedType class that implements the basic idea of this class in a Java 4 world where no generic types are present. However, it does allow Java 5 types to be modeled correctly. This class provides the capabilities to easily provide ReifiedTypes calculated from the Java 5 generics Type information. This class is maintained in extra package so the org.osgi.service.converter package can be compiled for Java 1.4. Constructor Summary GenericType(Type type) Public constructor. Method Summary ReifiedTyp e<?> getactualtypeargument(int index) Return the actual type argument for this type. Pag e 76 Pag e 77 Methods inherited from class org.osgi.service.converter.reifiedtype getrawclass, size Constructor Detail GenericType public GenericType(Type type) Public constructor. The constructor will analyze the type argument and find the type arguments, if any, as well as the raw class. Parameters: type - The type argument to be analyzed. OSGi Javadoc -- 8/30/10 Page 76 of 85

183 Interface AggregateFormatter Method Detail getactualtypeargument public ReifiedType<?> getactualtypeargument(int index) Return the actual type argument for this type. A type argument is the arguments between the < and > brackets. For example: Map<K, V> map; In this example, K and V are the type arguments. Each class has a hard number of type arguments. The GenericType class always returns GenericType instances. Overrides: getactualtypeargument in class ReifiedType Parameters: index - The index of the type argument. This value must be less than ReifiedType.size(), if not a ReifiedType on Object class is returned. Returns: The reified type for the index type argument OSGi Javadoc -- 8/30/10 Page 77 of 85

184 Interface Formatter Package org.osgi.service.formatter Formatter Package Version 1.0. See: Description Interface Summary AggregateForm atter The Aggregate Formatter service aggregates the Formatter services present in the service registry. Formatter A Formatter service can format an object to a CharSequence. 80 Package org.osgi.service.formatter Description Formatter Package Version 1.0. The purpose of this package is to provide access to a formatting service. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.formatter; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.formatter; version="[1.0,1.1)" Page 79 OSGi Javadoc -- 8/30/10 Page 78 of 85

185 Package org.osgi.service.threadio Interface AggregateFormatter org.osgi.service.formatter All Superinterfaces: Formatter public interface AggregateFormatter extends Formatter The Aggregate Formatter service aggregates the Formatter services present in the service registry. That is, a Formatter service provides the formatting facility for one or more types, an Aggregate Formatter service provides formatting for any object by using the Formatter services present in the service registry. When called, an Aggregate Formatter must use the Formatter.OSGI_FORMATTER_TYPE property of the Formatter services to determine which service to use. Finding the right formatter must follow the following rules: 1. Exact class 2. Exact implemented interfaces in order of declaration 3. Recursively for super class/super interface 4. for each interface in order of declaration: recursively for each interface If for any of the previous step multiple services apply, the service ranking rules must be used to determine the correct service. An Aggregate Formatter must not register with a Formatter.OSGI_FORMATTER_TYPE service property. The Aggregate Formatter service uses the same signature as the Formatter Service, the interface is therefore a marker interface to simplify getting access to the aggregator. ThreadSafe Fields inherited from interface org.osgi.service.formatter.formatter INSPECT, LINE, OSGI_FORMATTER_TYPE, PART Methods inherited from interface org.osgi.service.formatter.formatter format OSGi Javadoc -- 8/30/10 Page 79 of 85

186 Interface ThreadIO Interface Formatter org.osgi.service.formatter All Known Subinterfaces: AggregateFormatter public interface Formatter A Formatter service can format an object to a CharSequence. The purpose of a formatter is to create human readable output from general objects. The primary purpose is for the command shell, but other uses do exist. A key concept in the formatter is the level of detail that is displayed. In practice, the detail can vary depending on the use case. For this reason, there are three levels: 1. INSPECT - Provides the greatest level of detail. The output can consist of multiple lines. If columns are used, it is recommended to use 40 characters for the first column. However, the format of the output is more or less free. 2. LINE - This level is used to print collections. The output may consist of multiple lines but columns should have fixed width so they align. 3. PART - A cell in a table. Multiple lines must be separated with LF character ( ), not a CR or CR/LF. The end of the output must never be ended with a LF. The receiver must properly separate the output. Ranking. If two formatters have the same preference for conversion than the service with the highest ranking must be used. A formatter should follow the Locale objects given in the call. This list is in preferential order. If no locales are given the preference is the default locale and finally English. Version: $Id: 5b8af273ba1fe93c776d5ec83b1d16a3ef5adb3b $ ThreadSafe Field Summary int int String int INSPECT Print the object in detail using as many lines and columns as needed. LINE Print the object as a row in a table. OSGI_FORMATTER_TYPE This property is String+. PART Method Summary String Print the value in a small format so that it is identifiable. format(object target, int level, Locale... locales) Convert an object to a CharSequence object in the requested format. Pag e Pag e 81 Field Detail OSGI_FORMATTER_TYPE public static final String OSGI_FORMATTER_TYPE = "osgi.formatter.type" This property is String+. A string, or array/collection of strings, and specifies the names of the classes and/or interfaces that this Formatter service recognizes. Not setting this property indicates that this is an aggregate formatter. An aggregate formatter promises to use the existing Formatter services to convert and is thus not type specific. OSGi Javadoc -- 8/30/10 Page 80 of 85

187 Interface ThreadIO INSPECT public static final int INSPECT = 0 Print the object in detail using as many lines and columns as needed. For example, a Bundle object would be formatted with all its details like id, location, all its headers, registered services, etc. For this level, completeness is more important than space. The output can contain multiple lines but should not end in a LF (\n, ). LINE public static final int LINE = 1 Print the object as a row in a table. The columns should align for multiple objects printed beneath each other. For example, a bundle would print the primary information like the id, the state, the name, the version, but it would ignore the headers, registered services, etc. The print may run over multiple lines but must not end in a LF (\n, ). PART public static final int PART = 2 Print the value in a small format so that it is identifiable. For example, for a bundle it would print the id or bundle-symbolic name combination. If applicable, the constructor of the given class (assuming it is not an interface) should take the result of this formatting to reconstruct this object. Method Detail format String format(object target, int level, Locale... locales) throws Exception Convert an object to a CharSequence object in the requested format. The format can be INSPECT, LINE, or PART. Other values must throw IllegalArgumentException. Parameters: target - The object to be converted to a CharSequence object level - One of INSPECT, LINE, or PART. locales - A list of locales in order of preference. If no locales are specified, use the default locale and then english. Returns: A printed object of potentially multiple lines, must never be null. The return is a CharSequence because this is usually more efficient. Throws: Exception - If something fails during the formatting ### Should we make this with a StringBuilder arg? OSGi Javadoc -- 8/30/10 Page 81 of 85

188 Interface ThreadIO.Entry Package org.osgi.service.threadio Thread IO Package Version 1.0. See: Description Interface Summary ThreadIO Enable multiplexing of the standard IO streams for input, output, and error. 83 ThreadIO.Entry 84 Package org.osgi.service.threadio Description Thread IO Package Version 1.0. The purpose of this package is to provide thread based system IO. This service allows a unique System.out, System.in, and System.err stream on a per thread basis. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.threadio; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.threadio; version="[1.0,1.1)" Page OSGi Javadoc -- 8/30/10 Page 82 of 85

189 Interface ThreadIO Interface ThreadIO org.osgi.service.threadio public interface ThreadIO Enable multiplexing of the standard IO streams for input, output, and error. This service provides access the System I/O streams on a per thread basis. The standard streams are singletons, this service replaces the singletons with a service that has a per-thread stack of streams. If no streams are pushed output is directed to the original streams that were set before this service was started. Users can push a triplet of streams. After this push, all standard IO is redirected through the given streams for that thread only. When the user is ready, he can pop the streams and the previous situation is restored. Version: $Id: 09c67580f787107e8cdcb2978c7932d8f93bfce6 $ ThreadSafe Nested Class Summary static interface ThreadIO.Entry 84 Pag e Method Summary ThreadIO.E ntry pushstreams(inputstream in, PrintStream out, PrintStream err) Associate these streams with the current thread. Pag e 83 Method Detail pushstreams ThreadIO.Entry pushstreams(inputstream in, PrintStream out, PrintStream err) Associate these streams with the current thread. Ensure that when output is performed on System.in, System.out, System.err it will happen on the given streams. If a null is given for any of the parameters the stream must not be replaced. This method can be called multiple times on the same thread. A Thread IO implementation must stack these calls. It is paramount that users of this service ensure they follow the bracketing. The following code snippet provides such a model: threadio.pushstreams(in, out, err); try {... do real work } finally { threadio.pop(); } The streams will automatically be canceled when the bundle that has gotten this service is stopped or returns this service. If the ThreadIO service holds the only reference to a stream, it must remove this stream from the stack of streams. Parameters: in - InputStream to use for the current thread when System.in is used. If null then ignore. out - PrintStream to use for the current thread when System.out is used. If null then ignore. err - PrintStream to use for the current thread when System.err is used. If null then ignore. Returns: and entry that can be used to close/pop the push for life cycle control. OSGi Javadoc -- 11/12/10 Page 83 of 85

190 Interface ThreadIO.Entry Interface ThreadIO.Entry org.osgi.service.threadio Enclosing class: ThreadIO public static interface ThreadIO.Entry Method Summary void close() 84 Pag e Method Detail close void close() Java API documentation generated with DocFlex/Doclet v1.5.6 DocFlex/Doclet is both a multi-format Javadoc doclet and a free edition of DocFlex/Javadoc. If you need to customize your Javadoc without writing a full-blown doclet from scratch, DocFlex/Javadoc may be the only tool able to help you! Find out more at 6 Alternatives 7 Security Considerations Obviously, a shell language provides ample opportunities for malice. In principle, anything in the system is accessible, just like from Java. The protection against malicious behavior is based up the Java 2 security model. This allows the shell and all commands to be ignorant of any security issues, unless they want to perform operations that they have access to but a potential user has not. Such code must be executed in a dopriviliged block. The IO processors have the responsibility for protecting against malicious users. The specification hould copy some of the text of DMT Admin because it follows the same procedures OSGi Javadoc -- 11/12/10 Page 84 of 85

191 Interface ThreadIO.Entry 8 Document Support 8.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN Author s Address Name Company Address Peter Kriens aqute 9c, Avenue St. Drezery Voice [email protected] 8.2 Acronyms and Abbreviations 8.3 End of Document OSGi Javadoc -- 11/12/10 Page 85 of 85

192 RFC 160 Coordinator Service Draft 35 Pages Abstract A Coordinator service makes it possible to coordinate activities between independent parties. An initiator can start a Coordination and participants can participate by being called back at the end of the Coordination when completed successfully or failed. Coordinations can be pushed on a thread local stack to act as an implicit parameter for participants that are called downstream, or can be passed explicitly as a context parameter in a call. Coordinations can nest and provide a class based variable space for inter-participant communication. Copyright OSGi Alliance 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

193 RFC 160 Coordinator Service Page 2 of 35 Draft November 23, Document Information Table of Contents 0 Document Information... 2 Table of Contents... 2 Terminology and Document Conventions... 3 Revision History Introduction Application Domain Problem Description Requirements Use Cases... 7 Configuration Admin... 7 Remote Service Admin... 7 Deployment Admin... 8 Blueprint Configuration Admin Support Technical Solution... 8 The Coordinator Service... 8 States... 9 Direct Coordination Participating Failing Timeout Variables Thread Coordination Support Thread Safety Life Cycle Coordination Exception Command Line JMX API Javadoc Copyright OSGi Alliance 2010

194 RFC 160 Coordinator Service Page 3 of 35 Draft November 23, Considered Alternatives Prepare phase No Asynchronous Failure XA Resources Security Considerations Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in. Source code is shown in this typeface. Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial Initial Release Peter Kriens, aqute Additional use-case and comments David Bosschaert, Red Hat Comments from Ottawa meeting. Coordinations can be nested, they no longer automatically join the current Coordination Coordinations can be created without a thread local association Coordinations can be pushed/popped on a thread local stack There is now the concept of a current Coordination 0, Revisions for non-blocking/explicit API use case Copyright OSGi Alliance 2010

195 RFC 160 Coordinator Service Page 4 of 35 Draft November 23, 2010 Revision Date Comments Update after the Redwood Shores meeting and feedback from Apache Felix Add timeout parameter to begin/create. 0 = no timeout. Timeout means dont expire before here extended by the value. Time No more ReentrantParticipant, see #95 int end => void end throws exception on error. No terminate. The end method now throws an exception if the Coordination had failed, timeout, or was partially ended Coordination.participant(Participant) => Coordinator.addParticipant(Coordination, Participant) XXX boolean isfailed => Throwable getfailure Coordination names must conform to symbolic name grammar. Coordination has id which is monotonically increasing. getcoordinations returns a snapshot of the Coordinations. Coordination.getFailure must be callable in Participant methods. #96 Outer Coordinations that fail before their inner Coordinations are removed from the stack they are optionally on. #97, #99 Clarified the threads for callbacks which got confused due to extra requirements. #98 Variables section added #100 Added an isterminated method #101 Fixed Mbean constants #104 Service Life Cycle clarified #105 Removed participateorbegin Renamed the *.coordination package/project to *.coordinator Minor changes tot the text from experiences gained Added a join(timeout) method to wait for the end of a coordination Added a getthread() method for the associated threads Added a getcoordination(long) method to get a coordination by id Added a section about the Transaction Synchronization Registry in considered alternatives. Copyright OSGi Alliance 2010

196 RFC 160 Coordinator Service Page 5 of 35 Draft November 23, 2010 Revision Date Comments Moved the push() method to the Coordination Renamed getcurrentcoordination to peek Coordinator.fail redefined to return the value of the Coordination.fail method Removed Interrupting in certain cases Participants are not life cycle tracked, they should throw exceptions in their callback Allow implementations to limit the timeout of a Coordination Name of a Coordination must be a BSN pattern, throws IllegalArgument Exception otherwise 1 Introduction During the work on R4.3 it was found that we needed a mechanism to coordinate activities but that were not directly in touch with each other. The key example was configuration admin and the extension to support multiple PIDs on a MS. The MS would not know when the last PID was set and would therefore likely have to do too much work by updating its internal configuration for each PID that was set. This RFC introduces a lightweight API to coordinate activities to address the need for local coordination between services. This API is not a replacement for transactions because it does not support any persistence capabilities nor does it provide any of the strong guarantees transactions provide. 2 Application Domain In a service oriented programming model it is hard to know what parties will participate in the execution of some function. In principle, a single call to a service can result in many other calls. Services are implemented by more or less independent actors. There are two models for collaboration: calls on the same thread and calls between threads. Copyright OSGi Alliance 2010

197 RFC 160 Coordinator Service Page 6 of 35 Draft November 23, 2010 Java software calls methods on the same thread, this means that there is an implicit thread context between all methods that are being called. The ThreadLocal class creates a variable space that is based on the thread. Parties that need to coordinate their activities must establish a shared protocol. For example, Conditional Permission Admin creates an Updater object so that all updates being made can be treated atomically. This is a common pattern: Party A makes repeated updates and then commits all the changes in one go. Transactions support a bracketing model where an initiator can bracket a certain amount of work, ensuring that participants have the guarantee that they're called back at the end of the transaction. In JTA, this model was even opened to additional parties with the Synchronization Registry. The model discussed in this RFC has the following structure. A task is a piece of work that needs to be performed in a system. The task is begun by an initiator. The initiator begins the work and calls other participants.. The context for the work can be passed as a specific parameter or it can be stored in a thread local stack. A participant can decide to participate in the coordination or it can ignore it, participation is optional. A participant can also decide to fail the work by throwing an exception. When the parties return from the work they've done the initiator can clean up. 3 Problem Description Though transactions can be used for coordination, they carry are rather heavy overhead. To support the ACID characteristics it is necessary to know the resource managers before the system is started to be able to recover any transactions that were in limbo. Additionally, the overhead of a the usually distributed model as well as the complexity of the XAResource API makes transactions a rather heavy weight solution. The problem this RFC address is therefore that there is currently no light weight way to coordinate the execution of a task, where participants can see when they are required to participate as well as when the task fails or is finally terminated. In short, this RFC needs a coordination concept that allows multiple parties to coordinate the outcome of a task. 4 Requirements CO0001 Provide a solution to allow multiple parties that collaborate to coordinate the outcome of a task initiated by an initiator. CO0002 An initiator must be able to initiate a coordination and control the final outcome Copyright OSGi Alliance 2010

198 RFC 160 Coordinator Service Page 7 of 35 Draft November 23, 2010 CO0003 Any party participating in the task must be able to make the coordination always fail when ended. CO0004 Participants in the task must be informed when the coordination is terminated. CO0005 Participants must know that the coordination succeeded or failed at termination CO0006 A coordination must have a timeout CO0007 The timeout timer must be settable by the initiator CO0008 It must be possible to enumerate the participants CO0009 A participant must automatically be blocked when it attempts to participate on multiple coordinations in different threads. Participating in two coordinations on the same thread with the same participant is an error. CO0010 Participants must be able to prevent blocking CO0011 Coordinations must be allowed to nest where the nested coordination is independent of the outer coordinations. CO0012 The initiator must be informed if one of the participants throws an exception in the termination method for an ok outcome. CO0013 It must be possible to iterate the active coordinations CO0014 It must be possible to fail a coordination from outside of the initiating/active thread. CO0015 Provide an identifying mechanism for coordinations CO0016 Provide a simple way to either initiate a coordination or participate in an existing coordination. CO0017 Allow parties that make the coordination fail to provide information why it failed, the rationale for this requirement is that it is for trouble shooting CO0018 A Coordination must have a unique identification for management purposes CO0019 Provide an optional command line interface specification. CO0020 Provide an optional JMX based management interface. CO0021 All coordinations can be passed as parameters in method call Copyright OSGi Alliance 2010

199 RFC 160 Coordinator Service Page 8 of 35 Draft November 23, Use Cases Configuration Admin Configuration Admin allows Managed Service (Factory) services to use multiple PIDs, this is a recent change. However, it turns out that these PIDs will update the MS and MSF independently from each other, creating race conditions and inconsistencies. It is very hard to know for an MS or MSF that it has gotten the last update of a set. It can wait until all its PIDs are set but there are many scenarios where a new update can interfere. There is therefore a need for a management agent to bracket a number of updates to Configuration Admin. Updates to the MS and MSF must then wait until the bracket is closed. That is, at the time that all configurations are persisted. Remote Service Admin RSA manages the topology, the set of services mapping to external systems. Changing the topology can have a serious impact on the services, and those registrations and unregistrations can affect many different subsystems. In the current model a subsystem has no possibility to delay work until the topology has been completely changed, it is forced to do everything immediate. Though a delay can improve the situations it is much more complicated and provides no guarantees. Deployment Admin Deployment Admin takes a JAR file (a Deployment Pack) and from this DP it extracts bundles that it installs as well as resources, where the resources are processed through Resource Processors. A large number of services can be involved in installing and uninstalling a DP. Currently, all these activities are not bracketed, forcing each party to process the activities immediately. Blueprint Configuration Admin Support Like the previous use-case this one is also related to Configuration Admin, but at a slightly different level. Blueprint Configuration Admin support is worked on in RFC 156. One problem with configuration admin support for Blueprint is to marry the Blueprint style bean setter approach with the bracketing required to apply configuration changes at the right time. As an example take a bean that controls a thread pool in a system. This thread-pool has a high-watermark and a low-watermark. These watermarks are set through the Configuration Admin Service and injected into the bean using setlowwatermark() and sethighwatermark() injection methods. It is clearly important for the bean to know when the setting of configuration changes is finished so that it can apply the new thread pool values together as applying these new values individually would be highly inefficient or possibly even incorrect. A coordinator service could help in this situation making a callback to a configupdatefinished() or similar method once all the configuration changes had been set in the bean. Copyright OSGi Alliance 2010

200 RFC 160 Coordinator Service Page 9 of 35 Draft November 23, Technical Solution The Coordinator Service This RFC provides a Coordinator service. A Coordinator service allows an initiator to create or begin a Coordination.The initiator can now call other services passing the Coordination. The Coordination can be passed as a parameter or it can be associated with the current thread. Each thread will have a stack for nested Coordinations. A direct Coordination is a Coordination object passed as an parameter in a method call. A thread Coordination is pushed on the thread local stack. These downstream services can decide to participate on this coordination by registering themselves as a Participant with the Coordination object, or the Coordinator service for convenience in the case of a thread Coordination. When the initiator is finished, it calls the end() method on the Coordination object. The end() method will terminate the Coordination first. It then calls all registered participants to inform them that the Coordination has ended. Coordinations can also fail, in that case the participants will be informed of the negative outcome and the end() method will throw an exception detailing the failure. The basic model is depicted in the next schema, where the blank services represent arbitrary domain services. Name Each Coordination has name. This name must follow the follow the same patterns as defined for Bundle Symbolic Name. The name of the Coordination does not have to be unique, many Coordinations can share the same name. However, the CoordinationPermission can be used to limit the use of certain name patterns to certain bundles when security is on. It can therefore be used to ensure that only a limited set of bundles can participate in a Coordination. Copyright OSGi Alliance 2010

201 RFC 160 Coordinator Service Page 10 of 35 Draft November 23, 2010 States The following figure pictures the state diagram. Method/Event ACTIVE END FAIL entry notify participants by calling ended(). notify participants by calling failed(). exit terminate end() END PARTIALLY_ENDED addparticipant() DEADLOCK_DETECTED LOCK_INTERRUPTED throw ALREADY_ENDED throw ALREADY_ENDED throw FAILED throw FAILED fail() FAIL. Return true return false return false timeout event FAIL na na getvariables() return variables return variables return variables isterminated() return false return true return true getname() name name name getid() id id id State transitions must be atomic. That implies that a fail can return before the Coordination is properly ended when for example an end() is in progress and then fail() is called. In those cases the first call, as decided in a synchronized block, wins. Direct Coordination The Coordinator.create(name,timeout) creates a direct Coordination object. This object can be passed as argument to participants: Executor executor = final CountDownLatch latch = new CountdownLatch(10); final Coordination c = coordinator.create( name, 0); for ( int i=0; i<10; i++) { executor.execute( new Runnable() { public void run() { baz(c); latch.countdown(); } Copyright OSGi Alliance 2010

202 }); } latch.await(); c.end(); RFC 160 Coordinator Service Page 11 of 35 Draft November 23, 2010 The Coordination object is thread safe so it can be freely passed around. In the direct Coordination case, it is the responsibility of the initiator to properly synchronize. Participating Any participant that can get hold of the Coordination object can participate in the Coordination by calling addparticipant(participant). public class BusyBody implements Participant { volatile State state; } public void dowork(coordination coordination) { state = preparethings(); coordination.addparticipant(this); } public void ended(coordination c) { state.finalizethings(); state = null; } public void failed(coordination c) { state.undo(); } A specific Participant object can participate only in one Coordination. The following situations exist: Participant not participating in any Coordination Add it to the given Coordination and continue Participant occupied on another Coordination in another thread Lock until the other Coordination has notified all the Participants Participant occupied on another Coordination in same thread Throw a deadlock exception. The thread can only be determined when the first Coordination is pushed, see Thread Coordinations. If a participant does not want to be locked because it is reentrant then it should register a new handler for each participation. Locking is on object identity so creating a new object for each participation makes it possible to never lock. For example, the following code never locks: public class ReentrantBusyBody { volatile State state; public void dowork(coordination coordination) { state = preparethings(); coordination.addparticipant( new Participant() { public void ended(coordination c) { state.finalizethings(); state = null; } Copyright OSGi Alliance 2010

203 RFC 160 Coordinator Service Page 12 of 35 Draft November 23, 2010 } } ); } public void failed(coordination c) { state.undo(); } Or in the previous case, the state object could have implemented the Participant interface. public class AnotherBusyBody { } public void dowork(coordination coordination) { State state = preparethings(); coordination.addparticipant(state); } Using the Participant to block can be very useful to implement many locking patterns. Using the participant object (identity not equality) as the key for the lock makes it trivial to do course grained locking (the whole service is one lock, not allowing concurrency until the coordination is finished) or the locks can be fine grained, allowing concurrency. A participant can participate in the same Coordination multiple times by calling addparticipant() but will only be called back once when the Coordination is terminated. The Coordinator may throw a CoordinationException from the addparticipant() method when the participant lock times out or a deadlock is detected. The Participant interface has two methods: ended(coordination) The Coordination has successfully ended failed(coordination) The Coordination has failed. For each participant, it must be guaranteed that either of these methods is called exactly once after the Coordination is terminated. If a Coordination throws an exception in either method the termination process is deemed to be partially ended. Each exception should be logged with the Log Service. In the case of the failed() method this is ignored for the outcome but when this happens during the ended() method the end() method must end with a PARTIALLY_ENDED exception. Failing Any party can fail an ongoing Coordination by calling fail(throwable). This is a no-op when the Coordination has already terminated, in that case it returns false. Otherwise, this will immediately terminate the Coordination and call failed(coordination) on all participants and then return true to indicate that this call terminated the Coordination. The fail state can be checked with getfailure(). Fail can return before all participants have been called back. Any party can call fail(throwable) on any thread, implying that the failed(coordination) on Participant can also be called on any thread and are therefore required to be reentrant and thread safe. Copyright OSGi Alliance 2010

204 Timeout RFC 160 Coordinator Service Page 13 of 35 Draft November 23, 2010 If a Coordination is not properly terminated (either end() or fail(throwable) is not called) it will time out. A timeout will have the effect of fail(coordination.timeout), it will therefore follow the same process as failing. The Coordination.TIMEOUT field is a singleton Exception for this purpose. Initiators can find if a timeout occurs by reacting to the failure and then inspecting the exception from getfailure(). ### It was proposed to change this exception to a CoordinationException but this turned out to be wrong because a CoordinationException needs a Coordination for identity purposes. Turned out to be very silly. The timeout is explicitly specified in the Coordinator create() or begin() methods. Implementations may use configuration to specify a maximum timeout. A given timeout can be extended with the extendtimeout(int) method. This will add an additional timeout to the existing deadline, if a prior deadline was set. Implementations may have a (configurable) maximum timeout that can never be surpassed. Such a timeout is not visible in the API. That is, if a 0 (infinite) timeout is used, 0 is returned as deadline in extendtimeout but will in reality time out somewhere in the future. This maximum timeout should be reasonably long so that test cases are not unexpectedly influenced. Joining It is possible to wait for a Coordination to finish with the join() method. The join will return after the Coordination is terminated and all participants have been called back. Variables Each Coordination object has a Map<Class<?>,?> associated with it that can be gotten with getvariables() that must not be shared with any other Coordination. This map can be used by participants to store state that will be available during the callback. The map must remain available as long as the Coordination is reachable. The values in the map are not required to have the same type as the class. They can be any object. The returned Map requires synchronization on the map object for changes. That is, it does not have to be synchronized, clients must always synchronize on the map object while making changes. Thread Coordination Support The Coordinator supports a thread local stack for Coordinations. The top of this stack is the current Coordination, available via peek(). The Coordinator.begin(String,int) method creates a Coordination and pushes it on the top of the stack. The peek() method returns the current Coordination or null. Coordinations can be pushed and popped with the Coordination.push() and Coordinator.pop() method. The push() method is on the Coordination so that it can only be pushed on the Coordinator that created it. The Coordinator.begin method is identical in semantics to create + push. A Coordination can be pushed on the stack at most once. If a Coordination is already pushed a second time in any thread the ALREADY_PUSHED exception is thrown. Coordinations that are pushed therefore are associated with a specific thread. Once a Coordination is terminated it must automatically be removed from any stack it is on. A Coordination can not be pushed on the stack when it has been terminated, this will cause a ALREADY_ENDED exception. Copyright OSGi Alliance 2010

205 RFC 160 Coordinator Service Page 14 of 35 Draft November 23, 2010 To simplify life of the participants, the failed and addparticipant methods are replicated on the Coordinator, returning a boolean if there was a current Coordination active. A typical usage example is as follows: void foo() { Coordination c = coordinator.begin( foo, 10000); try { dowork(); } catch( Throwable e ) { c.fail(e); } finally { c.end(); } } void dowork() { State state = preparethings(); if (! state.isok() ) { coordinator.fail( new IllegalStateException() ); } if ( coordinator.addparticipant( state )) return; state.finishthings(); } Thread Safety A Coordination can timeout asynchronously and a management agent could asynchronously fail or end a Coordination. It is also possible that the ended() method is called on another thread than the initiator. An implementation must therefore provide the following guarantees: All objects, including the participants must be thread safe, all methods can be called from any thread. Either the Participant.ended(Coordination) or Participant.failed(Coordination) method is called once after the addparticipant method is returned without throwing an exception. The callback can happen before the addparticipant method has returned. An exception must be thrown when the end() method is called on a terminated Coordination. The Coordination.fail(Throwable) method can be called any number of times from any thread but can only have effect when the Coordination has not been terminated. fail(throwable) must not block if a Coordination is in the process of being terminated. A second failure must not override the getfailure() result. A Participant must always see a terminated Coordination in its callback. Termination (via end() or fail(throwable)) must be atomic. Variables require synchronizing on the Map object Copyright OSGi Alliance 2010

206 Life Cycle RFC 160 Coordinator Service Page 15 of 35 Draft November 23, 2010 Coordinations are bound to the bundle that initiated them. If this bundle ungets the Coordinator service then any Coordinations the bundle created created through this service must fail. In practice this means that Coordinator implementations must use a Service Factory to register their services. If the initiator ungets the service, all Coordinations created through to that service instance must fail with a ServiceException(UNREGISTERED) if they are not yet terminated. The life cycle of participants is NOT tracked. A participant of a bundle that is stopped or does not longer want to participate should ensure that it throws an exception in the ended() method to (partially) fail the Coordination. Though it would be possible to also track the participant's lifecycle the short duration of Coordinations made it better to not handle this case. If the thread dies that has active Coordinations associated with it then implementations may fail this Coordination. However, in the normal case the timeout should take care of cleaning this up. Implementations should, as always, ensure that garbage collection is least impacted when people hang on to Coordinations. 7 Javadoc OSGi Javadoc 11/23/10 12:21 PM Package Summary org.osgi.servic e.coordinator Coordinator Package Version Page Copyright OSGi Alliance 2010

207 Package org.osgi.service.coordinator Package org.osgi.service.coordinator Coordinator Package Version 1.0. See: Description Interface Summary Coordination A Coordination object is used to coordinate a number of independent participants. 17 Coordinator A Coordinator service coordinates activities between different parties. 28 Participant A Participant participates in a Coordination. 32 Class Summary CoordinationP ermission The name parameter of the Permission is a filter expression. 26 Page Page Exception Summary CoordinationE xception Thrown when an implementation detects a potential deadlock situation that it cannot solve. Page 22 Package org.osgi.service.coordinator Description Coordinator Package Version 1.0. Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package. Example import for consumers using the API in this package: Import-Package: org.osgi.service.coordinator; version="[1.0,2.0)" Example import for providers implementing the API in this package: Import-Package: org.osgi.service.coordinator; version="[1.0,1.1)" OSGi Javadoc -- 11/23/10 Page 16 of 35

208 Interface Coordination Interface Coordination org.osgi.service.coordinator public interface Coordination A Coordination object is used to coordinate a number of independent participants. Once a Coordination is created (through Coordinator.begin(String, int) or Coordinator.create(String, int), it can be used to add Participant objects. When the Coordination is ended, the participants are called back on the Participant.ended(Coordination) method. A Coordination can also fail for various reasons, in that case the participants are informed of this failure by calling their Participant.failed(Coordination) method. A Coordination is in two states, either ACTIVE or TERMINATED. The transition between this state must be atomic, ensuring that a participant can be guaranteed of a callback or exception when registering. A Coordination object is thread safe and can be passed as a parameter to other parties regardless of the threads these parties use. ThreadSafe Field Summary Exception TIMEOUT The TIMEOUT exception is a singleton exception that will the reason for the failure when the Coordination times out. Pag e 18 Method Summary void void long boolean Throwable long String List<Parti cipant> Thread Map<Class<?>,Object> addparticipant(participant participant) Add a Participant to this Coordination. end() End the current Coordination. extendtimeout(long timeinmillis) Extend the time out. fail(throwable reason) Fail this Coordination. getfailure() If the coordination has failed because fail(throwable) was called then this method can provide the Throwable that was given as argument to the fail(throwable) method. getid() A system assigned ID unique for a specific registered Coordinator. getname() Return the name of this Coordination. getparticipants() Return a mutable snapshot of the participants that joined the Coordination. getthread() Answer the associated thread or null. getvariables() A utility map associated with the current Coordination. boolean isterminated() 21 void Coordinati on join(long timeoutinmillis) Wait until the Coordination is terminated and all Participant objects have been called. push() Associate the given Coordination object with a thread local stack of its Coordinator. Pag e OSGi Javadoc -- 11/23/10 Page 17 of 35

209 Interface Coordination Field Detail TIMEOUT public static final Exception TIMEOUT The TIMEOUT exception is a singleton exception that will the reason for the failure when the Coordination times out. Method Detail getid long getid() A system assigned ID unique for a specific registered Coordinator. This id must not be reused as long as the Coordinator is registered and must be monotonically increasing for each Coordination and always be positive. Returns: an id getname String getname() Return the name of this Coordination. The name is given in the Coordinator.begin(String,int) or Coordinator.create(String,int) method. The name should follow the same naming pattern as a Bundle Symbolc Name. Returns: the name of this Coordination fail boolean fail(throwable reason) Fail this Coordination. If this Coordination is not terminated, fail it and call the Participant.failed(Coordination) method on all participant on the current thread. Participants must assume that the Coordination failed and should discard and cleanup any work that was processed during this Coordination. The fail(throwable) method will return true if it caused the termination. A fail method must return silently when the Coordination has already finished and return false. The fail method must terminate the current Coordination before any of the failed methods are called. That is, the Participant.failed(Coordination) methods must be running outside the current coordination, adding participants during this phase will cause a Configuration Exception to be thrown. If the Coordination is pushed on the Coordinator stack it is associated with a specific thread. Parameters: reason - The reason of the failure, must not be null Returns: true if the Coordination was active and this coordination was terminated due to this call, otherwise false OSGi Javadoc -- 11/23/10 Page 18 of 35

210 Interface Coordination end void end() throws CoordinationException End the current Coordination. void foo() throws CoordinationException { Coordination c = coordinator.begin("work", 0); try { dowork(); } catch (Exception e) { c.fail(e); } finally { c.end(); } } If the coordination was terminated this method throws a Configuration Exception. Otherwise, any participants will be called on their Participant.ended(Coordination) method. A successful return of this end() method indicates that the Coordination has properly terminated and any participants have been informed of the positive outcome. It is possible that one of the participants throws an exception during the callback. If this happens, the coordination fails partially and this is reported with an exception. This method must terminate the current Coordination before any of the Participant.ended(Coordination) methods are called. That is, the Participant.ended(Coordination) methods must be running outside the current coordination, no participants can be added during the termination phase. If the Coordination is on a thread local stack then it must be removed from this stack during termination. Throws: CoordinationException - when the Coordination has (partially) failed or timed out. 1. CoordinationException.PARTIALLY_ENDED 2. CoordinationException.ALREADY_ENDED 3. CoordinationException.FAILED 4. CoordinationException.UNKNOWN getparticipants List<Participant> getparticipants() Return a mutable snapshot of the participants that joined the Coordination. Each unique Participant object as defined by its identity occurs only once in this list. Returns: list of participants. Throws: SecurityException - This method requires the CoordinationPermission.ADMIN action for the CoordinationPermission. getfailure Throwable getfailure() If the coordination has failed because fail(throwable) was called then this method can provide the Throwable that was given as argument to the fail(throwable) method. A timeout on this Coordination will set the failure to a TimeoutException. Returns: a Throwable if this Coordination has failed, otherwise {code null} if no failure occurred. OSGi Javadoc -- 11/23/10 Page 19 of 35

211 Interface Coordination addparticipant void addparticipant(participant participant) throws CoordinationException Add a Participant to this Coordination. Once a Participant is participating it is guaranteed to receive a call back on either the Participant.ended(Coordination) or Participant.failed(Coordination) method when the Coordination is terminated. A participant can be added to the Coordination multiple times but it must only be called back once when the Coordination is terminated. A Participant can only participate at a single Coordination, if it attempts to block at another Coordination, then it will block until prior Coordinations are finished. Notice that in edge cases the call back can happen before this method returns. The ordering of the call-backs must follow the order of participation. If participant is participating multiple times the first time it participates defines this order. Parameters: participant - The participant of the Coordination Throws: CoordinationException - This exception should normally not be caught by the caller but allowed to bubble up to the initiator of the coordination, it is therefore a RuntimeException. It signals that this participant could not participate the current coordination. This can be cause by the following reasons: 1. CoordinationException.DEADLOCK_DETECTED - Tried to lock the participant but it was already locked on another Configuration on the same thread 2. CoordinationException.ALREADY_ENDED - The Coordination has already ended 3. CoordinationException.LOCK_INTERRUPTED - The current thread was interrupted while waiting for the lock 4. CoordinationException.FAILED - The Coordination has failed 5. CoordinationException.UNKNOWN SecurityException - This method requires the CoordinationPermission.PARTICIPATE action for the current Coordination, if any. getvariables Map<Class<?>,Object> getvariables() A utility map associated with the current Coordination. Each coordination carries a map that can be used for communicating between different participants. To namespace of the map is a class, allowing for private date to be stored in the map by using implementation classes or shared data by interfaces. The returned map is does not have to not synchronized. Users of this map must synchronize on the Map object while making changes. Returns: The potentially unsynchronized map extendtimeout long extendtimeout(long timeinmillis) throws CoordinationException Extend the time out. Allows participants to extend the timeout of the coordination with at least the given amount. This can be done by participants when they know a task will take more than normal time. This method returns the new deadline. Passing 0 will return the existing deadline. Parameters: timeinmillis - Add this timeout to the current timeout. If the current timeout was set to 0, no extension must take place. A zero or negative value must have no effect. OSGi Javadoc -- 11/23/10 Page 20 of 35

212 Interface Coordination Returns: the new deadline in the format of System.currentTimeMillis() or 0 if no timeout was set. Throws: CoordinationException - Can throw 1. CoordinationException.ALREADY_ENDED 2. CoordinationException.FAILED 3. CoordinationException.UNKNOWN isterminated boolean isterminated() Returns: true if this Coordination is terminated otherwise false getthread Thread getthread() Answer the associated thread or null. Returns: Associated thread or null join void join(long timeoutinmillis) throws InterruptedException Wait until the Coordination is terminated and all Participant objects have been called. Parameters: timeoutinmillis - Maximum time to wait, 0 is forever Throws: InterruptedException - If the wait is interrupted push Coordination push() throws CoordinationException Associate the given Coordination object with a thread local stack of its Coordinator. The top of the thread local stack is returned with the Coordinator.peek() method. To remove the Coordination from the top call Coordinator.pop(). Returns: this (for the builder pattern purpose) Throws: CoordinationException - Can throw the 1. CoordinationException.ALREADY_PUSHED 2. CoordinationException.UNKNOWN OSGi Javadoc -- 11/23/10 Page 21 of 35

213 Class CoordinationException Class CoordinationException org.osgi.service.coordinator java.lang.object java.lang.throwable java.lang.exception All Implemented Interfaces: Serializable java.lang.runtimeexception org.osgi.service.coordinator.coordinationexception public class CoordinationException extends RuntimeException Thrown when an implementation detects a potential deadlock situation that it cannot solve. The name of the current coordination is given as argument. Field Summary static int static int static int static int static int static int static int static int ALREADY_ENDED The Coordination was already ended. ALREADY_PUSHED A Coordination was pushed on the stack that was already pushed. DEADLOCK_DETECTED Adding a participant caused a deadlock. FAILED The Coordination was failed with Coordination.fail(Throwable). LOCK_INTERRUPTED Interrupted while trying to lock the participant. PARTIALLY_ENDED The Coordination was partially ended. TIMEOUT The Coordination timed out. UNKNOWN Unknown reason for this exception. Constructor Summary CoordinationException(String message, Coordination coordination, int reason) Create a new Coordination Exception. CoordinationException(String message, Coordination coordination, int type, Throwable exception) Create a new Coordination Exception. Pag e Pag e Method Summary Throwable getfailure() Must be set of the exception type is FAILED. long getid() 25 Pag e 24 String int getname() Answer the name of the Coordination associated with this exception. gettype() Answer the reason OSGi Javadoc -- 11/23/10 Page 22 of 35

214 Class CoordinationException Field Detail UNKNOWN public static final int UNKNOWN = 0 Unknown reason for this exception. DEADLOCK_DETECTED public static final int DEADLOCK_DETECTED = 1 Adding a participant caused a deadlock. FAILED public static final int FAILED = 3 The Coordination was failed with Coordination.fail(Throwable). When this exception type is used, the getfailure() method must return a non-null value. PARTIALLY_ENDED public static final int PARTIALLY_ENDED = 4 The Coordination was partially ended. ALREADY_ENDED public static final int ALREADY_ENDED = 5 The Coordination was already ended. ALREADY_PUSHED public static final int ALREADY_PUSHED = 6 A Coordination was pushed on the stack that was already pushed. LOCK_INTERRUPTED public static final int LOCK_INTERRUPTED = 7 Interrupted while trying to lock the participant. TIMEOUT public static final int TIMEOUT = 9 OSGi Javadoc -- 11/23/10 Page 23 of 35

215 Class CoordinationException The Coordination timed out. Constructor Detail CoordinationException public CoordinationException(String message, Coordination coordination, int type, Throwable exception) Create a new Coordination Exception. Parameters: message - The message coordination - The coordination that failed type - The reason for the exception. exception - The exception CoordinationException public CoordinationException(String message, Coordination coordination, int reason) Create a new Coordination Exception. Parameters: message - The message coordination - The coordination that failed reason - The reason for the exception. Method Detail getname public String getname() Answer the name of the Coordination associated with this exception. Returns: the Coordination name gettype public int gettype() Answer the reason. Returns: the reason getfailure public Throwable getfailure() OSGi Javadoc -- 11/23/10 Page 24 of 35

216 Class CoordinationException Must be set of the exception type is FAILED. Returns: If exception type is FAILED a Throwable getid public long getid() Returns: Answer the id OSGi Javadoc -- 11/23/10 Page 25 of 35

217 Class CoordinationPermission Class CoordinationPermission org.osgi.service.coordinator java.lang.object java.security.permission java.security.basicpermission All Implemented Interfaces: Guard, Serializable org.osgi.service.coordinator.coordinationpermission public class CoordinationPermission extends BasicPermission The name parameter of the Permission is a filter expression. It asserts the bundle that is associated with the coordination. Additionally, the following attributes can be asserted: 1. coordination.name - The name of the coordination Coordinator INITIATE PARTICIPATE ADMIN NONE alwaysfail(string) - begin(string) + - getcoordinations() + - isactive() isfailed() participate(participant) + - participateorbegin(participant) + and + - Coordination end() + fail(string) + getname() + getparticipants() + - isfailed() + settimeout(long) terminate() + ### Need to complete the implementation! Field Summary static String static String static String ADMIN The action string admin. INITIATE Initiate a Coordination. PARTICIPATE The action string participate. Pag e Constructor Summary CoordinationPermission(String filterexpression, String actions) The name parameter specifies a filter condition. CoordinationPermission(org.osgi.framework.Bundle bundle, String coordinationname, String actions) The verification permission Pag e OSGi Javadoc -- 11/23/10 Page 26 of 35

218 Class CoordinationPermission Field Detail INITIATE public static final String INITIATE = "initiate" Initiate a Coordination. An owner of this permission can initiate, end, fail, and terminate a Coordination. ADMIN public static final String ADMIN = "admin" The action string admin. PARTICIPATE public static final String PARTICIPATE = "participate" The action string participate. Constructor Detail CoordinationPermission public CoordinationPermission(String filterexpression, String actions) The name parameter specifies a filter condition. The filter asserts the bundle that initiated the Coordination. An implicit grant is made for a bundle's own coordinations. Parameters: filterexpression - A filter expression asserting the bundle associated with the coordination. actions - A comma separated combination of INITIATE, ADMIN, PARTICIPATE. CoordinationPermission public CoordinationPermission(org.osgi.framework.Bundle bundle, String coordinationname, String actions) The verification permission Parameters: bundle - The bundle that will be the target of the filter expression. coordinationname - The name of the coordination or null actions - The set of actions required, which is a combination of INITIATE, ADMIN, PARTICIPATE. OSGi Javadoc -- 11/23/10 Page 27 of 35

219 Interface Coordinator Interface Coordinator org.osgi.service.coordinator public interface Coordinator A Coordinator service coordinates activities between different parties. The Coordinator can create Coordination objects. Once a Coordination object is created, it can be pushed on a thread local stack Coordination.push() as an implicit parameter for calls to other parties, or it can be passed as an argument. The current top of the thread local stack can be obtained with peek(). The addparticipant(participant) method on this service or the Coordination.addParticipant(Participant) method can be used to participate in a Coordination. Participants participate only in a single Coordination, if a Participant object is added to a second Coordination the Coordination.addParticipant(Participant) method is blocked until the first Coordination is terminated. A Coordination ends correctly when the Coordination.end() method is called before termination or when the Coordination fails due to a timeout or a failure. If the Coordination ends correctly, all its participants are called on the Participant.ended(Coordination) method, in all other cases the Participant.failed(Coordination) is called. The typical usage of the Coordinator service is as follows: Coordination coordination = coordinator.begin("mycoordination",0); try { dowork(); } finally { coordination.end(); } In the dowork() method, code can be called that requires a callback at the end of the Coordination. The dowork method can then add a Participant to the coordination. This code is for a Participant. void dowork() { if (coordinator.addparticipant(this)) { beginwork(); } else { beginwork(); finishwork(); } } void ended() { finishwork(); } void failed() { undowork(); } Life cycle. All Coordinations that are begun through this service must automatically fail before this service is ungotten. ThreadSafe Method Summary boolean Coordinati on Coordinati on addparticipant(participant participant) Participate in the current Coordination and return true or return false if there is none. begin(string name, int timeoutinmillis) Begin a new Coordination and push it on the thread local stack with Coordination.push(). create(string name, int timeout) Create a new Coordination that is not associated with the current thread. Pag e OSGi Javadoc -- 11/23/10 Page 28 of 35

220 Interface Coordinator boolean Coordinati on Collection <Coordinat ion> Coordinati on Coordinati on fail(throwable reason) Always fail the current Coordination, if it exists. getcoordination(long id) Answer the coordination associated with the given id if it exists. getcoordinations() Provide a mutable snapshot collection of all Coordination objects currently not terminated. peek() Return the current Coordination or null. pop() Pop the top of the thread local stack of Coordinations Method Detail create Coordination create(string name, int timeout) Create a new Coordination that is not associated with the current thread. Parameters: name - The name of this coordination, a name does not have to be unique. The name must follow the bundle symbolic name pattern, e.g. com.example.coordination. timeout - Timeout in milliseconds, less or equal than 0 means no timeout Returns: The new Coordination object, never null Throws: SecurityException - This method requires the CoordinationPermission.INITIATE action, no bundle check is done. IllegalArgumentException - when the name does not match the Bundle Symbolic Name pattern getcoordinations Collection<Coordination> getcoordinations() Provide a mutable snapshot collection of all Coordination objects currently not terminated. Coordinations in this list can have terminated before this list is returned or any time thereafter. The returned collection must only contain the Coordinations for which the caller has CoordinationPermission.ADMIN, without this permission an empty list must be returned. Returns: a list of Coordination objects filter by CoordinationPermission.ADMIN. fail boolean fail(throwable reason) Always fail the current Coordination, if it exists. If this is no current Coordination return false. Otherwise return the result of Coordination.fail(Throwable), which is true in the case this call terminates the Coordination and false otherwise. false false true - No current Coordination - Current Coordination was already terminated - Current Coordination got terminated due to this call OSGi Javadoc -- 11/23/10 Page 29 of 35

221 Interface Coordinator Parameters: reason - The reason for failure, must not be null. Returns: true if there was a current Coordination and it was terminated, otherwise false. peek Coordination peek() Return the current Coordination or null. The current Coordination is the top of the thread local stack of Coordinations. If the stack is empty, there is no current Coordination. Returns: null when the thread local stack is empty, otherwise the top of the thread local stack of Coordinations. begin Coordination begin(string name, int timeoutinmillis) Begin a new Coordination and push it on the thread local stack with Coordination.push(). Parameters: name - The name of this coordination, a name does not have to be unique. The name must follow the bundle symbolic name pattern, e.g. com.example.coordination. timeoutinmillis - Timeout in milliseconds, less or equal than 0 means no timeout Returns: A new Coordination object Throws: SecurityException - This method requires the CoordinationPermission.INITIATE action, no bundle check is done. IllegalArgumentException - when the name does not match the Bundle Symbolic Name pattern pop Coordination pop() Pop the top of the thread local stack of Coordinations. If no current Coordination is present, return null. Returns: The top of the stack or null addparticipant boolean addparticipant(participant participant) throws CoordinationException Participate in the current Coordination and return true or return false if there is none. This method calls peek(), if it is null, it will return false. Otherwise it will call Coordination.addParticipant(Participant). Parameters: participant - The participant of the Coordination OSGi Javadoc -- 11/23/10 Page 30 of 35

222 Interface Coordinator Returns: true if there was a current Coordination that could be successfully used to participate, otherwise return false. Throws: CoordinationException - This exception should normally not be caught by the caller but allowed to bubble up to the initiator of the coordination, it is therefore a RuntimeException. It signals that this participant could not participate the current coordination. This can be cause by the following reasons: 1. CoordinationException.DEADLOCK_DETECTED 2. CoordinationException.ALREADY_ENDED 3. CoordinationException.FAILED 4. CoordinationException.UNKNOWN SecurityException - This method requires the CoordinationPermission.PARTICIPATE action for the current Coordination, if any. getcoordination Coordination getcoordination(long id) Answer the coordination associated with the given id if it exists. Parameters: id - The id of the requested Coordination Returns: a Coordination with the given ID or null when Coordination cannot be found because it never existed or had terminated before this call. Throws: SecurityException - if the caller has no CoordinationPermission.ADMIN for the requested Coordination. OSGi Javadoc -- 11/23/10 Page 31 of 35

223 Interface Participant Interface Participant org.osgi.service.coordinator public interface Participant A Participant participates in a Coordination. A Participant can participate in a Coordination by calling Coordinator.addParticipant(Participant). After successfully initiating the participation, the Participant is called back when the Coordination is terminated. If a Coordination ends with the Coordination.end() method, then all the participants are called back on their ended(coordination) method. If the Coordination is failed (someone has called Coordination.fail(Throwable) then the failed(coordination) method is called back. Participants are required to be thread safe for the ended(coordination) method and the failed(coordination) method. Both methods can be called on another thread. ThreadSafe Method Summary void ended(coordination c) The Coordination is being ended. void failed(coordination c) The Coordination has failed and the participant is informed. Pag e Method Detail failed void failed(coordination c) throws Exception The Coordination has failed and the participant is informed. A participant should properly discard any work it has done during the active coordination. Parameters: c - The Coordination that does the callback Throws: Exception - Any exception thrown should be logged but is further ignored and does not influence the outcome of the Coordination. ended void ended(coordination c) throws Exception The Coordination is being ended. Parameters: c - The Coordination that does the callback Throws: Exception - If an exception is thrown it should be logged and the return of the Coordination.end() method must throw CoordinationException.PARTIALLY_ENDED. Java API documentation generated with DocFlex/Doclet v1.5.6 DocFlex/Doclet is both a multi-format Javadoc doclet and a free edition of DocFlex/Javadoc. If you need to customize your Javadoc without writing a full-blown doclet from scratch, DocFlex/Javadoc may be the only tool able to help you! Find out more at OSGi Javadoc -- 11/23/10 Page 32 of 35

224 Interface Participant 8 Considered Alternatives Prepare phase The original design had an isagreed() method on the Participant. Before the end() method decided to pass or fail it would consult all the participants. If any participant decided to return false or throw an exception, the end method would assume a VETO and call failed on all participants. This phase was discarded because it did not provide sufficient value for the given use cases. No Asynchronous Failure The original design did not allow the fail(string) method to be called except on the Coordination thread. This significantly simplified the implementation. However, the result is that bad code could easily leave a Coordination hanging, and thereby locking the participants. It was therefore decided that a timeout must really fail all participants, regardless of any cooperation of the initiator, despite the significant added complexity that this causes in the implementation. XA Resources During one of the conference calls it was suggested to skip the Coordinator and instead use JTA with XA Resources. JTA and XA Resources are not lightweight solutions, one of the primary requirements. JTA is primary and all encompassing focus is to provide durable consistency, exactly this part is missing from the Coordinator requirements. Implementing an XA Resource is significant piece of work because an XA Resource object represent the resource manager and not the actual participation on a specific Coordination/Transaction. The XA Resource must be able to handle many different concurrent scenarios and must multiplex transaction activities via the Xid. For the design goal of XA Resources this is not a major problem because it is small in comparison to maintaining the ACID model, especially in the light of recoverability after a crash. Compare the interfaces of the Participant and the XAResource: void commit(xid xid, boolean onephase) Commits the global transaction specified by xid. void end(xid xid, int flags) Ends the work performed on behalf of a transaction branch. void forget(xid xid) Tells the resource manager to forget about a heuristically completed transaction branch. int gettransactiontimeout() Obtains the current transaction timeout value set for this XAResource instance. boolean issamerm(xaresource xares) This method is called to determine if the resource manager instance represented by the target object is the same as the resouce manager instance represented by the parameter xares. int prepare(xid xid) Ask the resource manager to prepare for a transaction commit of the transaction specified in xid. Xid[] recover(int flag) Obtains a list of prepared transaction branches from a resource manager. void rollback(xid xid) OSGi Javadoc -- 11/23/10 Page 33 of 35

225 Interface Participant Informs the resource manager to roll back work done on behalf of a transaction branch. boolean settransactiontimeout(int seconds) Sets the current transaction timeout value for this XAResource instance. void start(xid xid, int flags) Starts work on behalf of a transaction branch specified in xid. Additionally, application servers make every attempt to hide transactions for the application developer and are very cautious letting third parties participate in transactions. It is a primary design goal of the Coordinator that many services leverage the Coordinator. Coordinations instead are a very lightweight model to allow different service implementations to collaborate. If XA Resource were used for this then it would be unlikely that it would be used. Transaction Synchronization Registry The Transaction Synchronization Registry was looked upon as well. However, this class and the corresponding Synchronization class is tightly coupled to the Transaction classes. Using this class would imply much more guarantees that the Coordinator can perform. However, it should be straightforward to use the Transaction Synchronization Registry and transactions to implement the Coordinator. 9 Security Considerations This specification provides a Coordination Permission. This permission can enforce the name of the coordination as well as the initiating bundle. The permission therefore uses a filter as name, as defined in the filter based permissions section in the core specification. There is one additional parameter for the filter: coordination.name The following actions are defined: 1. INITIATE Required to initiate a Coordination, implies PARTICIPATE. 2. PARTICIPATE Required to participate a Coordination. 3. ADMIN Required to administrate a Coordinator, implies INITIATE and PARTICIPATE The permissions are indicated in the following table (+=required): * Coordinator * fail(exception) PARTICIPATE * begin(string,int) INITIATE * create(string,int) INITIATE * getcoordinations() ADMIN * getcoordination(long) ADMIN * addparticipant(participant) PARTICIPATE * push(coordination) INITIATE * pop() INITIATE * Coordination * end() INITIATE * fail(string) PARTICIPATE * getname() * getid() OSGi Javadoc -- 11/23/10 Page 34 of 35

226 Interface Participant * getparticipants() INITIATE * isterminated() * getfailure() PARTICIPATE * extendtimeout(long) PARTICIPATE * addparticipant(participant) PARTICIPATE * join(long) PARTICIPATE * getthread() ADMIN * getvariables() PARTICIPATE ###? 10Document Support References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN Author s Address Name Company Address Peter Kriens aqute 9c, Avenue St. Drezery Voice Peter [email protected] Name Company Address David Bosschaert Red Hat 6700 Cork Airport Business Park, Kinsale Road, Cork, Ireland Voice [email protected] Acronyms and Abbreviations End of Document OSGi Javadoc -- 11/23/10 Page 35 of 35

227 Enterprise Design Documents OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Revision November OSGi Alliance.

228 RFC Blueprint Service Configuration Admin Support Draft 20 Pages Abstract This RFC extends the Blueprint service to support Configuration Admin. Copyright VMware 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

229 RFC Blueprint Service Configuration Admin Support Page 2 of 20 Draft November 22, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Problem Description Requirements Technical Solution Considered Alternatives Security Considerations Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in 8.1. Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Copyright VMware 2010

230 RFC Blueprint Service Configuration Admin Support Page 3 of 20 Draft November 22, 2010 Revision Date Comments 0 18/12/09 First draft. Glyn Normington, VMware, [email protected] /08/10 Convert David Bosschaert's requirements into problem descriptions for discussion. Glyn Normington /01/10 Rework following review at Southampton F2F. Start on the technical solution section as input to the prototype. Glyn Normington /01/10 Explain the technical solution. Glyn Normington /01/10 Revise the technical solution and explain that it is simply the starting point for a prototype. Move property placeholder section to considered alternatives. Glyn Normington /03/10 Enumerate the requirements. Glyn Normington /03/10 Note RFC 144 in section 3.2 Glyn Normington /06/10 Update technical solution to reflect London F2F discussion except that updating by deleting and recreating a component is relegated to considered alternatives. Glyn Normington /06/10 Clarify technical solution. Glyn Normington /11/10 Revise technical solution based on meeting with IBM and discussion at Walldorf F2F. Acknowledge the lazy config requirement from OSGi bug Glyn Normington Copyright VMware 2010

231 RFC Blueprint Service Configuration Admin Support Page 4 of 20 Draft November 22, Introduction Blueprint components need to be configured using Configuration Admin. Spring DM, which inspired the Blueprint service, has some support for Config Admin which will be used to inform this design. This RFC relies on the support for namespaces being added to the Blueprint Service by RFC 155 see reference [3]. The work to standardize Config Admin support began in RFC see reference [4]. However, the requirements and technical solution did not stabilize in time for R4.2. This RFC captures the requirements for Config Admin support and proposes a solution. Note that this RFC will be developed in parallel with a prototype implementation based on the Blueprint service reference implementation. 2 Application Domain The Blueprint service enables an OSGi bundle to define Java objects known as components using a XML configuration file stored in the bundle. Components may be published as services in the service registry and may consume services from the service registry. The Config Admin service provides a standard way of supplying configuration to OSGi bundles. Configuration is grouped into key->value dictionaries identified by Persistent Id (PID). The Blueprint and Config Admin services are described in the R4.2 Service Compendium - see reference [5]. 2.1 Dictionaries The Configuration Admin service allows the creation, dissemination, and persistence of configurations for objects (which may be bundles, devices, or other resources) in an OSGi framework environment. Configurations are represented as Config Admin dictionaries mapping keys to values. We use the term `key' rather than property name to avoid ambiguity with `component properties' which are basic to the Blueprint service. 2.2 Configuration Admin Config Admin is a collection of dictionaries indexed by persistent identity or PID. Copyright VMware 2010

232 RFC Blueprint Service Configuration Admin Support Page 5 of 20 Draft November 22, 2010 Updating a configuration adds a new PID and dictionary or updates the dictionary associated with an existing PID. Deleting a configuration removes a PID and its dictionary. 3 Problem Description Add concrete use cases that are actually required. Avoid the temptation to make up use cases. 3.1 Updates Although the full set of use cases for update will require a callback, the simple case should be possible without a callback. The basic problem is to define a mapping (per PID) from key to property. This mapping can be provided by a callback or by a declaration. Spring DM supports bean managed and container managed update strategies (which are no longer mutually exclusive in Spring DM 2.0). The bean managed update strategy is a bulk update callback to a bean method. This provides flexibility of locking and could also support the incremental update defined by RFC 150 see reference [6]. The container managed update strategy is less flexible. All the properties in the updated Config Admin dictionary are set in turn inside a single synchronized block (on the bean object). This approach to synchronization is questionable as it exposes the object's concurrency control mechanism to callers. It can also lead to deadlocks as there is no way to drop the monitor if it is necessary to make an alien call to another class. 3.2 Relationship of Components to PIDs There needs to be an arbitrary relationship between PIDs and configured components. A single component must be able to consume properties from zero or more PIDs. A single PID must be capable of configuring zero or more components. Config Admin has a basic restriction that distinct bundles may not access the same PID (and some other restrictions on Managed Factories which may not be relevant) but, apart from that, Spring DM satisfies these requirements. RFC 144 will lift this restriction. 3.3 Config Admin Dictionary Key to Bean Property Mappings It should be possible to map Config Admin keys to property names. For example, a key 'com.acme.size' could be mapped to a property called 'size'. Spring DM supports this via the bean-managed update strategy. The callback method can invoke whatever property setters it likes. 3.4 Defaults There needs to be a way of specifying default values for keys which are not supplied in a PID's Config Admin dictionary. Copyright VMware 2010

233 RFC Blueprint Service Configuration Admin Support Page 6 of 20 Draft November 22, 2010 Spring DM supports specifying default property value in a cm-properties element which may be used as input to a property placeholder configurer. The following example demonstrates this. <?xml version="1.0" encoding="utf-8"?> <beans xmlns=" xmlns:xsi=" xmlns:osgi=" xmlns:osgix=" xmlns:context=" xsi:schemalocation="[omitted]"> </beans> <!-- Obtain properties from Config Admin dictionary with PID=caprops. The dictionary has the following properties: day=7, snow=true, dayofweek=thursday, year=2010. Note: properties are injected when the bean is created but are not updated subsequently if the Config Admin dictionary changes. --> <osgix:cm-properties id="caprops.cfg" persistent-id="caprops"> </osgix:cm-properties> <!-- Provide some default property values --> <prop key="month">january</prop> <prop key="year">1970</prop> <!-- Property placeholder configurer referencing properties from Config Admin. --> <context:property-placeholder properties-ref="caprops.cfg" /> <!-- Bean referencing properties using placeholders. --> <bean id="abean" class="rfc0156.ca0.bean"> </bean> <!-- int day comes from Config Admin --> <property name="day" value="${day}"></property> <!-- String month comes from default --> <property name="month" value="${month}"></property> <!-- int year comes from Config Admin overriding default --> <property name="year" value="${year}"></property> <!-- boolean snow comes from Config Admin --> <property name="snow" value="${snow}"/> Spring also supports specifying property values for a bean which can be used in conjunction with Spring DM to provide default values for properties which are omitted from a Config Admin dictionary. The following example demonstrates this. The <bean> and <property> elements are supported by the Blueprint service. <?xml version="1.0" encoding="utf-8"?> <beans xmlns=" xmlns:xsi=" xmlns:osgi=" xmlns:osgix=" xmlns:context=" Copyright VMware 2010

234 RFC Blueprint Service Configuration Admin Support Page 7 of 20 xsi:schemalocation="[omitted]"> Draft November 22, 2010 <!-- Bean referencing managed properties using Config Admin. --> <bean id="abean" class="rfc0156.dynamic.dynamicbean"> <osgix:managed-properties persistent-id="caprops-dyn" update-strategy="container-managed" /> </bean> <!-- Provide some default property values --> <property name="month" value="january" /> <property name="year" value="1970" /> </beans> 3.5 Property Types It should be possible to support all the data types supported by Configuration Admin. Section of the Config Admin spec limits values to the following types: type ::= simple vector arrays simple ::= String Integer Long Float Double Byte Short Character Boolean primitive ::= long int short char byte double float boolean arrays ::= primitive [] simple [] vector ::= Vector of simple By default, Spring DM supports certain types other than String such as int and boolean. The filter syntax in section 3.2 of the core specification may help here. 4 Requirements REQ-MULTI-PID-COMP: It MUST be possible to configure a given component using zero or more PIDs. REQ-MULTI-COMP-PID: It MUST be possible to configure zero or more components using a given PID. REQ-MAP-KEYS-TO-PROPS: It SHOULD be possible to specify how Config Admin dictionary keys are mapped to component property names. Copyright VMware 2010

235 RFC Blueprint Service Configuration Admin Support Page 8 of 20 Draft November 22, 2010 REQ-DEFAULT-PROPS: It MUST be possible to specify default values for keys which are not supplied in a PID's Config Admin dictionary. REQ-PROP-TYPES: It SHOULD be possible to support properties of all the data types supported by Config Admin. REQ-UPDATE: When the Config Admin dictionary for a given PID is updated, any components configured using that PID MUST be reconfigured with the new dictionary. REQ-LAZY-CONFIG: It SHOULD be possible to wait for configuration to become available. See OSGi bug 1793 for background. 5 Technical Solution The technical solution will be developed in parallel with a prototype. In order for the prototyping to begin, the following starting point is proposed. We need to describe how dictionary keys and component property names are related, how to specify defaults when a dictionary does not provide all the property values a component requires, how to reference multiple dictionaries from a component, and what to do when any of the referenced dictionaries are updated or deleted. The following sections examine the solutions to these requirements. The solution uses a custom namespace indicated by the cm: namespace qualifier. 5.1 Specifying a Config Admin PID The requirement REQ-MULTI-COMP-PID states: It MUST be possible to configure zero or more components using a given PID. A PID may be specified at any of three levels: the whole blueprint, a particular component, a particular property of a particular component. A PID for a whole blueprint is specified on the blueprint element and applies to all the blueprint XML files in a given bundle, for example: <blueprint cm:pid= some.pid...>... </blueprint> If conflicting PIDs are specified on distinct blueprint elements in the same bundle, this is an error and it is not defined which PID(s) are used for the whole blueprint. The prototype may tighten up the rules in this case. A PID for a component is specified on the bean element and overrides any PID specified for the whole blueprint in the sense that a lookup using a given Config Admin dictionary key tries the component PID first and only if the key is not found tries the blueprint PID. The following is a simple example of a PID specified for a component: Copyright VMware 2010

236 <bean id= bean cm:pid= other.pid...>... </bean> RFC Blueprint Service Configuration Admin Support Page 9 of 20 Draft November 22, 2010 A PID for a particular property of a particular component is specified on the property element and overrides any PIDs specified for the component and for the whole blueprint in the sense that a lookup using a given Config Admin dictionary key tries the property PID first, and if the key is not found, tries any component PID next, and only if the key is again not found, tries any blueprint PID. The following is a simple example of a PID specified for a property: <bean id= bean cm:pid= other.pid...> <property name= myprop cm:pid= yet.another.pid cm:key= org.foo.prop /> </bean> 5.2 Specifying Multiple Config Admin PIDs The requirement REQ-MULTI-PID-COMP in RFC 156 states: It MUST be possible to configure a given component using zero or more PIDs. We allow a list of one or more PIDs to be specified by the cm:pid attribute of a property element, a component element, or a blueprint element. PIDs later in the list take precedence over PIDs earlier in the list essentially the list is searched backwards. For example, the following component element specifies two PIDs with pid2 taking precedence over pid1. <bean... cm:pid="pid1 pid2"...> 5.3 Mapping Property Names to Keys The requirement REQ-MAP-KEYS-TO-PROPS states: It SHOULD be possible to specify how Config Admin dictionary keys are mapped to component property names. We overload the property element to specify the Config Admin dictionary key for a given component property. Note there is no requirement to be able to map multiple dictionary keys to the same property name as that would instantly create confusion when both keys exist but are mapped to distinct values. For example, the following property map a Config Admin dictionary key to a corresponding property: <property name= size cm:key="com.acme.size"/> Note that this solution does not provide a way to avoid specifying both the property and the key when the two are equal. This may not be critical since the two are specified as attributes of the same element and so are less likely to get out of step than if they were in separate elements. However, the prototype should explore the possibility of omitting the name attribute when the key is specified and the two are equal. This would require deferring part of the validation of the blueprint until after namespace processing has finished. 5.4 Default Configuration Requirement REQ-DEFAULT-PROPS states: It MUST be possible to specify default values for keys which are not supplied in a PID's Config Admin dictionary. Copyright VMware 2010

237 RFC Blueprint Service Configuration Admin Support Page 10 of 20 Draft November 22, 2010 Configuration defaults are specified using the value attribute of the property element. Such a default value applies if and only if the Config Admin dictionary key is not found in any PID specified for the property, any PID specified for the component, and any PID specified for the whole blueprint. For example, the following component specifies default values for two properties. <bean id="def" osgix= some.pid > <property name="host" value="localhost" cm:key= host /> <property name="port" value="8080" cm:key= port /> </bean> 5.5 Update The requirement REQ-UPDATE states: When the Config Admin dictionary for a given PID is updated, any components configured using that PID MUST be reconfigured with the new dictionary. When the contents of Config Admin changes a component that was configured using Config Admin may need to be updated. Changes in Config Admin include new PIDs being created, dictionaries associated with existing PIDs being updated, PIDs being deleted, or arbitrary combinations of creations, updates and deletions. If a change occurs in Config Admin which means that a component would have been configured differently than it was originally, then the component properties may need to be updated. Two strategies are supported: restarting the whole blueprint and setting updated properties. The default strategy is to restart the whole blueprint. The strategy may be specified on a blueprint element. If conflicting strategies are specified, the blueprint restart strategy wins Update by Restarting the Blueprint This is the simplest strategy for the component developer and is the default strategy. A change to any of the Config Admin PIDs which are referenced by the blueprint XML files of a given bundle causes the whole blueprint to be destroyed and recreated if and only if this is specified on at least one of the blueprint elements of the bundle: <blueprint... cm:updatestrategy= restart > Again a batch of changes, as enabled by RFC 150, should be applied with one restart. This may be implemented by remembering the versions associated with the PIDs applied to a blueprint. The feasibility of restarting the whole blueprint, which is likely to be required in other circumstances such as when a custom namespace goes away, is to be validated by the prototype Update by Setting Properties When an update occurs, property setters are called to apply updates for all the PIDs specified by a blueprint. This ensures that a batch of updates, as enabled by RFC 150, is applied in one step since update notifications are sent after all the Config Admin PIDs in the batch are updated. This strategy requires that the components of the blueprint, or at least those which have properties provided by Config Admin, are thread safe. Apart from protecting the internal state of these components, thread safety ensures that updates made by a given thread are published safely and are visible to other threads. The calling of property setters is optionally bracketed by calls to user-defined begin update and end update methods. If either or both of these methods are not specified, then the corresponding methods are not called. Copyright VMware 2010

238 RFC Blueprint Service Configuration Admin Support Page 11 of 20 Draft November 22, 2010 Begin update and end update methods must be parameterless with a void return type. If either of the named methods does not exist or has the wrong signature, it is ignored (although the implementation may choose to log diagnostics). The configuration changes for a component bracketed by begin update and end update methods correspond to either a single update of a Config Admin PID or a batch of updates as defined by RFC 150. A component may specify begin and end update methods in XML syntax using beginupdate and endupdate attributes which name methods of the component's class. These attributes are optional. For example, the following component element specifies both begin update and end update methods. <component... cm:beginupdate="beginmethod" cm:endupdate="endmethod" > This strategy may be specified on a blueprint element as follows: <blueprint... cm:updatestrategy= setproperties > 5.6 Non-String Property Types The requirement REQ-PROP-TYPES states: It SHOULD be possible to support properties of all the data types supported by Config Admin. The solution, likely to be inspired by Spring DM, will be specified after the initial prototype is complete. 5.7 Lazy Configuration The requirement REQ-LAZY-CONFIG states: It SHOULD be possible to wait for configuration to become available. The solution, likely to be inspired by Spring DM, will be specified after the initial prototype is complete. 6 Considered Alternatives 6.1 PropertyMapping based solution The following sections show an earlier iteration of the technical solution Mapping Property Names to Keys The requirement REQ-MAP-KEYS-TO-PROPS states: It SHOULD be possible to specify how Config Admin dictionary keys are mapped to component property names. Copyright VMware 2010

239 RFC Blueprint Service Configuration Admin Support Page 12 of 20 Draft November 22, 2010 We introduce the concept of a property mapping from property names to dictionary keys. A property mapping is the opposite way round to the requirement so that it is a function. There is no requirement to be able to map, for example, two dictionary keys to the same property name as that would instantly create confusion when a single dictionary contained both keys but mapped to distinct values. There is a fixed, default way of mapping property names to dictionary keys which applies to any property names not covered by a property mapping: any property name not covered by a property mapping is mapped to the dictionary key equal to the property name. A property mapping is specified in XML as part of a configselector element (described in section Error: Reference source not found) enclosing a series of propertymapping elements, each of which maps a single property name, identified by a property attribute, to a key identified by a key attribute. If a given configselector encloses more than one propertymapping element for a given property name, the first propertymapping encountered is honoured and the others are ignored. For example, the following property mapping maps two Config Admin dictionary keys to corresponding properties: <osgix:propertymapping property="size" key="com.acme.size"/> <osgix:propertymapping property="color" key="com.acme.color"/> Configuration Selection The requirement REQ-MULTI-COMP-PID states: It MUST be possible to configure zero or more components using a given PID. A configuration selector identifies a PID and optionally specifies a property mapping. A configuration selector has an identifier so that it may be referred to by zero or more components. A dictionary identified by the selector's PID is mapped using the selector's property mapping to produce some component properties (destined for injection into components). If the selector's PID does not exist in Config Admin, then no component properties are produced. A configuration selector is specified in XML using a configselector element identified by an id attribute, specifying a PID by a persistent-id attribute, and optionally enclosing one or more propertymapping elements. For example, the following configuration selector specifies its identity, a PID, and a property mapping. <osgix:configselector id="cs1" persistent-id="com.acme.apid"> <osgix:propertymapping property="p1" key="key1" /> <osgix:propertymapping property="p2" key="key2" /> </osgix:configselector> Default Configuration Requirement REQ-DEFAULT-PROPS states: It MUST be possible to specify default values for keys which are not supplied in a PID's Config Admin dictionary. Configuration defaults are specified as a mapping from property name to default value. Configuration defaults are specified in XML using a series of property elements, each of which specifies a property name identified by a name attribute and a default value identified by a value attribute. Copyright VMware 2010

240 RFC Blueprint Service Configuration Admin Support Page 13 of 20 Draft November 22, 2010 If more than one property element specifies a given property name, the first property element encountered is honoured and the others are ignored. Values are specified as strings and for non-string properties, a type conversion is attempted at runtime. If the type conversion fails, the default is not applied (although implementations may log diagnostics). For example, the following default configuration specifies default values for two properties. <osgix:defaults id="def"> <osgix:property name="p1" value="default1" /> <osgix:property name="p2" value="default2" /> </osgix:defaults> Component Configuration The requirement REQ-MULTI-PID-COMP in RFC 156 states: It MUST be possible to configure a given component using zero or more PIDs. We allow a component to specify a sequence of configuration selectors which will be used to configure the component. The configuration selectors are applied in order so that later configuration selectors in the sequence take precedence over earlier configuration selectors. In addition, we allow a component optionally to specify a default configuration which provides values for properties not determined by any sequence of configuration selectors. Components may specify a sequence of configuration selectors in XML using a configselectorrefs attribute which consists of a comma separated sequence of one or more configuration selector element identifiers. Components may specify a default configuration using a defaultsref attribute which consists of a single defaults element identifier. For example, the following component element specifies a sequence of two configuration selectors and a default configuration. <component... osgix:configselectorrefs="cs1,cs2" osgix:defaultsref="def" > 6.2 Property Placeholders The popular ${variable} syntax shown in the example below is a Spring property placeholder. Supporting this syntax would add considerable complexity, such as additional lifecycle states, into the Blueprint service specification and implementations. Specifying individual properties using placeholders is usable for simple use cases with few properties, but it may not be ideal for supporting Config Admin updates. The point here is to make the syntax as readable and intuitive as the property placeholder syntax. The following example shows the use of property placeholders: <?xml version="1.0" encoding="utf-8"?> <beans xmlns=" xmlns:xsi=" xmlns:osgi=" xmlns:osgix=" xmlns:context=" xsi:schemalocation="[omitted]"> <!-- Copyright VMware 2010

241 RFC Blueprint Service Configuration Admin Support Page 14 of 20 Draft November 22, 2010 Obtain properties from Config Admin dictionary with PID=caprops. --> <osgix:cm-properties id="caprops.cfg" persistent-id="caprops" /> <!-- Property placeholder configurer referencing properties from Config Admin. --> <context:property-placeholder properties-ref="caprops.cfg" /> <!-- Bean referencing properties using placeholders. --> <bean id="abean" class="rfc0156.ca0.bean"> </bean> <!-- int day comes from Config Admin --> <property name="day" value="${day}"></property> </beans> 6.3 RFC 124 Configuration Administration Service Support RFC 124 proposed the following technical solution, closely modeled on the Config Admin support in Spring DM. The osgix namespace defines configuration elements and attributes supporting the OSGi Compendium Services. Currently the only service with dedicated support in this namespace is the Configuration Admin service Property Placeholder Support Component property values may be sourced from the OSGi Configuration Administration service. This support is enabled via the property-placeholder element. The property placeholder element provides for replacement of delimited string values (placeholders) in component property expressions with values sourced from the configuration administration service. The required persistent-id attribute specifies the persistent identifier to be used as the key for the configuration dictionary. The default delimiter for placeholder strings is "${...}". Delimited strings can then be used for any property value of any component, and will be replaced will the configuration administration value with the given key. Given the declarations: <osgix:property-placeholder persistent-id="com.xyz.myapp"/> <component id="somecomponent" class="aclass"> <property name="timeout" value="${timeout}"/> </component> Then the timeout property of somecomponent will be set using the value of the timeout entry in the configuration dictionary registered under the com.xyz.myapp persistent id. The placeholder strings are evaluated at the time that the component is instantiated. The evaluation results in a new string which is then interpreted as if it were the originally declared value. Changes to the properties made via Configuration Admin subsequent to the creation of the component do not result in re-injection of property values. See the managed-properties and managed-service-factory elements if you require this level of integration. The placeholder-prefix and placeholder-suffix attributes can be used to change the delimiter strings used for placeholder values. It is a configuration error to define multiple property-placeholder Copyright VMware 2010

242 RFC Blueprint Service Configuration Admin Support Page 15 of 20 Draft November 22, 2010 elements using the same prefix and suffix, and a ComponentDefinitionException will be thrown during context creation if such conflicting declarations are found. It is possible to specify a default set of property values to be used in the event that the configuration dictionary does not contain an entry for a given key. The defaults-ref attribute can be used to refer to a named component of Properties or Map type. Instead of referring to an external component, the default-properties nested element may be used to define an inline set of properties. <osgix:property-placeholder persistent-id="com.xyz.myapp"> <osgix:default-properties> <property name="productcategory" value="e792"/> <property name="businessunit" value="811"/> </osgix:default-properties> </osgix:property-placeholder>property placeholder declarations have module context scope, and apply to any matching placeholder string regardless of the particular configuration file of the module the property placeholder and placeholder string declarations happen to be in.if a property referenced via a placeholder definition is not defined in the configuration dictionary, and no default value has been specified, then a runtime ComponentDefinitionException will be thrown during module context creation. The persistent-id attribute must refer to the persistent-id of an OSGi ManagedService, it is a configuration error to specify a factory persistent id referring to a ManagedServiceFactory. Placeholder expressions can be used in any attribute value, as the whole or part of the value text Publishing Configuration Admin properties with exported services Using the property-placeholder support it is easy to publish any named configuration-admin property as a property of a service exported to the service registry. For example: <service interface="myinterface" ref="myservice"> <service-properties> <entry key="akey" value="${property.placeholder.key}"/> </service-properties> </service> To publish all of the public properties registered under a given persistent-id as properties of an exported service, without having to explicitly list all of those properties up-front, use the nested cm-properties element. <service interface="org.osgi.service.cm.managedservice" ref="mymanagedservice"> <service-properties> <osgix:cm-properties persistent-id="pid"/> </service-properties> </service> Only public properties registered under the pid (properties with a key that does not start with ".") will be published. To have the advertised service properties updated when the configuration stored under the given persistent id is update, specify the optional update="true" attribute value. Copyright VMware 2010

243 6.3.3 Managed Properties RFC Blueprint Service Configuration Admin Support Page 16 of 20 Draft November 22, 2010 The managed-properties element can be nested inside a component declaration in order to configure component properties based on the configuration information stored under a given persistent id. It has one mandatory attribute, persistent-id. An example usage of managed properties follows: <component id= mycomponent class= AClass > <osgix:managed-properties persistent-id="com.xyz.messageservice"/> <!-- other component declarations as needed --> </component> For each key in the dictionary stored by configuration admin under the given persistent id, if the component type has a property with a matching name (following JavaBeans conventions), then that component property will be dependency injected with the value stored in configuration admin under the key. If the definition of AClass from the example above is as follows: public class AClass { } private int amount; public void setamount(int amount) { this.amount = amount; } public int getamount() { return this.amount; } and the configuration dictionary stored under the pid com.xyz.messageservice contains an entry amount -> 200, then the setamount method will be invoked on the component instance during configuration, passing in the value 200. If a property value is defined both in the configuration dictionary stored in the Configuration Admin service, and in a property element declaration nested in the component element, then the value from Configuration Admin takes precedence. Property values specified via property elements can therefore be treated as default values to be used if none is available through Configuration Admin. The configuration data stored in Configuration Admin may be updated after the component has been created. By default, any updates post-creation will be ignored. To receive configuration updates, the update-strategy attribute can be used with a value of either component-managed or container-managed. The default value of the optional update-strategy attribute is none. If an update strategy of componentmanaged is specified then the update-method attribute must also be used to specify the name of a method defined on the component class that will be invoked if the configuration for the component is updated. The update method must have one of the following signatures: public void anymethodname(map properties) public void anymethodname(map<string,?> properties); // for Java 5 When an update strategy of container-managed is specified then the container will re-inject component properties by name based on the new properties received in the update. For container-managed updates, the component class must provide setter methods for the component properties that it wishes to have updated. For each property in the updated configuration dictionary where the component class has a matching setter method, the setter method will be called with the new value. Copyright VMware 2010

244 6.3.4 Managed Service Factories RFC Blueprint Service Configuration Admin Support Page 17 of 20 Draft November 22, 2010 The Configuration Admin service supports a notion of a Managed Service Factory (see section in the Compendium Specification). A managed service factory is identified by a factory pid, Configuration objects can be associated with the factory. Configuration objects associated with the factory can be added or removed at any point. The managed-service-factory element defines a managed set of services. For each configuration object associated with the factory pid of the managed service factory, an anonymous component instance is created and registered as a service. The lifecycle of these component instances is tied to the lifecycle of the associated configuration objects. If a new configuration object is associated with the factory pid, a new component instance is created and registered as a service. If a configuration object is deleted or disassociated from the factory pid then the corresponding component instance is destroyed. The attributes of the managed-service-factory element are: id (required) factory-pid (required) this specifies the persistent id of the managed service factory in the Configuration Admin service interface, auto-export, and ranking, all with the same semantics as the attributes with the corresponding names defined on the <service> element. These attributes apply to each service registered on behalf of the managed service factory. Optionally nested inside the managed-service-factory element are the interfaces, service-properties, and registration-listener elements, with the same syntax and semantics as when used nested inside of a service element. A single nested managed-component element is required inside the managed-service-factory. The managed component declaration defines the component template for the component instances to be created and exposed as services. Managed component supports the same set of nested elements as for a component, and a subset of the attributes: class, init-method, destroy-method, factory-method and factorycomponent. The signature of a destroy-method for a managed-component must follow the format: public void anymethodname(int reasoncode); where reason code is one of: ModuleContext.CONFIGURATION_ADMIN_OBJECT_DELETED ModuleContext.BUNDLE_STOPPING To have the properties of a managed component configured from the properties stored in its associated configuration object, simply use the nested managed-properties element as in the following example. The pid for the configuration object is automatically generated by the Configuration Admin service, and is different for each managed component instance. When the managed component instance is published as a service, the service.pid property is set to the value of the pid for its associated configuration object. A convention is adopted that specifying an empty string for the value of the persistent-id attribute when used nested inside of a managed-service-factory means the persistent id of my associated configuration object. Copyright VMware 2010

245 RFC Blueprint Service Configuration Admin Support Page 18 of 20 Draft November 22, 2010 <managed-service-factory id="foofactory" factory-pid="my.pid" interface="foo"> <managed-component class="someclass"> <managed-properties persistent-id="" update-strategy= container-managed /> <property name="foo" ref="someothercomponent"/> </managed-component> </managed-service-factory> Given the above definition, an instance of SomeClass will be created for each configuration object associated with the managed service factory my.pid. The instances are dependency injected with the properties found in the configuration object dictionary, and the property foo is also dependency injected with a reference to someothercomponent. Each instance is registered as a service advertising the Foo interface. The same convention of using an empty persistent-id attribute value applies to the config-properties too when nested inside a managed-service-factory element. The following example will publish all of the public properties from the associated configuration object as service properties of the service published for the associated managed component. <managed-service-factory id="foofactory" factory-pid="my.pid" interface="foo"> <osgi:service-properties> <config-properties persistent-id= /> </osgi:service-properties> <managed-component class="someclass"> <property name="foo" ref="someothercomponent"/> </managed-component> </managed-service-factory> The component defined by a managed-service-factory is of type Map<ServiceRegistration,Object> and contains one entry for each service published by it where the key is the service registration object, and the value is the service itself. The Map membership is dynamically managed as configuration objects (and hence their associated services) come and go. A typical use case for the managed service factory element might be to publish a DataSource service for each configuration object associated with the data.source factory pid. Adminstrators can then define, configure and publish new DataSource services simply by updating configuration information in the Configuration Admin service Direct access to configuration data If you need to work directly with the configuration data stored under a given persistent id or factory persistent id, the easiest way to do this is to register a service that implements either the ManagedService or ManagedServiceFactory interface and specify the pid that you are interested in as a service property. For example: <service interface="org.osgi.service.cm.managedservice" ref="mymanagedservice"> <service-properties> <entry key="service.pid" value="my.managed.service.pid"/> </service-properties> </service> Copyright VMware 2010

246 RFC Blueprint Service Configuration Admin Support Page 19 of 20 Draft November 22, 2010 <component id="mymanagedservice" class="com.xyz.mymanagedservice"/> where the class MyManagedService implements org.osgi.service.cm.managedservice. 6.4 Update option to recycle a component This option was proposed as a simplified way of updating a component. The component would be deleted and recreated when its configuration changed. However this considerably complicates the lifecycle behaviour of components when we consider components which reference the deleted component (and components which reference those components, and so on transitively). Essentially this approach re-introduces the complexity of reinjecting properties into components. 7 Security Considerations None. 8 Document Support 8.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. RFC 155 is available in the OSGi Alliance subversion repository in rfcs/rfc0155/rfc-155-blueprintnamespaces.pdf. [4]. RFC 124 v1.0 available in the OSGi Alliance subversion repository in rfcs/rfc0124/rfc-124.pdf. [5]. OSGi Release 4 Version 4.2 Service Compendium. [6]. RFC 150 Configuration Admin Enhancements is available in the OSGi Alliance subversion repository in rfcs/rfc0150/rfc-0150-configadminenhancements.pdf. Copyright VMware 2010

247 8.2 Author s Address Name Glyn Normington RFC Blueprint Service Configuration Admin Support Page 20 of 20 Draft November 22, 2010 Company Address VMware SpringSource, Kenneth Dibben House, Enterprise Road, Chilworth, Southampton SO16 7NS, UK. Voice [email protected] 8.3 Acronyms and Abbreviations Configuration Admin is usually referred to as Config Admin (but never as Configuration Administration). 8.4 End of Document Copyright VMware 2010

248 Blueprint Declarative Transaction Draft 17 Pages Abstract Blueprint declarative transaction provides container managed transaction for blueprint beans which enables application developers to focus on the application logic and provides better separation of application and infrastructure code. Copyright OSGi Alliance 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

249 Blueprint Declarative Transaction Page 2 of 17 Draft November 16, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Overview Sample User Scenario Problem Description Requirements Technical Solution Related RFCs Blueprint Transaction XML Schema The Transaction Element The Method Attribute The Transaction Attribute The Bean Attribute Transaction Examples At Bean Level Transaction Examples At Bundle Wide Level Transaction Examples At Bean Level And Bundle Wide Level Sample User Scenario Command Line API JMX API Initial Spec Chapter Considered Alternatives Security Considerations Document Support References...16 Copyright OSGi Alliance 2010

250 Blueprint Declarative Transaction Page 3 of 17 Draft November 16, Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial 07/12/2010 Initial version Lin Sun, IBM [email protected] /26/2010 Address additional comments - 1. Disallow two *s next to each other 2. Ability to specify bundle wide transaction /17/2010 Simplified the rules to determine the transaction attribute Simplified the value for the method and bean attributes /16/2010 Add: statement for synthetic beans. Clarify namespace handler requirement and a few minor errors here and there. Mark transaction attribute as optional and default to Required. 1 Introduction Copyright OSGi Alliance 2010

251 Blueprint Declarative Transaction Page 4 of 17 Draft November 16, 2010 RFP 138 was approved which defined requirements for blueprint declarative transaction. This RFC describes the means to use blueprint interceptors and customized blueprint namespace to support blueprint declarative transaction. 2 Application Domain 2.1 Overview The Blueprint Container specification version 1.0 in OSGi Compendium Release 4.2 defines a dependency injection framework for OSGi bundles that understands the unique dynamic nature of services. Bundles in this programming model contain a number of XML definition resources which are used by the Blueprint Container to wire the application together and start it when the bundle is active. The Java Transaction API (JTA) Transaction Services specification in OSGi Enterprise Release 4.2 is based on JTA 1.1 specification and defines the use of JTA through 3 transaction services: User Transaction, Transaction Manager, and Transaction Synchronization. With these two specifications, a blueprint application developer can obtain the transaction services from the OSGi service registry, set the transaction boundaries and manage the transaction in the application code. However, this is no defined method to enable the developer to declare transactional demarcation for blueprint components and no defined contract that a blueprint container could offer when processing such transactional declarations. 2.1 Sample User Scenario The blueprint container manages various components such as bean, service, reference-list and reference elements. Blueprint beans are declared using the bean element. The following defines a single bean called TestBeanImpl implemented by the POJO org.apache.aries.simple.testbeanimpl. blueprint.xml <?xml version="1.0" encoding="utf-8"?> <blueprint xmlns=" <bean id="testbeanimpl" class="org.apache.aries.simple.testbeanimpl" /> </blueprint> If a transaction is required in the POJO org.apache.aries.simple.testbeanimpl, the application Copyright OSGi Alliance 2010

252 Blueprint Declarative Transaction Page 5 of 17 Draft November 16, 2010 developer would currently have to obtain the User Transaction service from OSGi service registry, set the boundaries of transaction and manage the transaction in the application code, for example the insertrow method in TestBeanImpl.java: TestBeanImpl.java public class TestBeanImpl { public TestBeanImpl() {... } public void insertrow(string name, int value) throws SQLException { // get the user transaction service UserTransaction ut = getusertransactionservice(); // begin the user transaction ut.begin(); } } try { // start the operation to insert name, value into the db... } finally { // commit the user transaction ut.commit(); } This form of transaction management can be referred to as application managed transactions or bean managed transactions, whereby the bean code explicitly manages the boundaries of the transaction. Given that the primary purpose of a container is to manage the lifecycle and qualities of service of the entities it contains, it is desirable to define a standard mechanism for container to manage transactions on behalf of those entities. This enables the bean developer to focus on the application logic and provides better separation of application and infrastructure code. A useful model to refer to that is extremely familiar to Java EE developers is the Java EE enterprise bean with container managed transactions, where the Enterprise Java Bean (EJB) container manages the boundaries of the transactions. The vast majority of enterprise beans use container-managed rather than bean-managed transactions. Copyright OSGi Alliance 2010

253 Blueprint Declarative Transaction Page 6 of 17 Draft November 16, Problem Description It is possible that a transaction is required in one or more methods of the blueprint managed components defined in blueprint XML definition. The blueprint container specification does not describe a means to allow application developers to define transaction attributes (such as Required, RequiresNew, NotSupported, Supports, Mandatory and Never, as provided by the EJB container) in the blueprint XML definition. Instead, if an application developer has chosen to use the blueprint container to manage his bundles, the application developer would have to set the transaction boundary and manage the transaction in the application code, whenever a transaction is required. There is no container managed transaction defined for blueprint components. This proposal is to provide container managed transaction for blueprint managed components, where application developers can use blueprint XML definition to declare transactions and their associated transaction attributes within one or more methods of the blueprint container managed components, so that the transaction can be managed by the container automatically based on the specified transaction attributes and the bean methods to which they apply. 4 Requirements BDT01 - Blueprint Declarative Transaction must support these types of Transaction attributes: (Required, RequiresNew, NotSupported, Mandatory, Supports and Never). BDT02 - Blueprint Declarative Transaction must support configuration at the blueprint bean level. BDT03 - Blueprint Declarative Transaction must support configuration at the bean method level. BDT04 - Blueprint Declarative Transaction must support configuration of a default transaction attribute that can be overridden by more specific declarations. BDT05 - Blueprint Declarative Transaction must define the container's behavior for completing transactions in the presence of a normal successful method execution or exception. Copyright OSGi Alliance 2010

254 Blueprint Declarative Transaction Page 7 of 17 Draft November 16, 2010 BDT06 Blueprint declarative transaction must be configurable in blueprint XML definition file. BDT07 - It MUST be possible to implement Blueprint Declarative Transactions using Blueprint Interceptors. BDT08 - Blueprint Declarative Transactions MUST define a custom namespace. 5 Technical Solution 5.1 Related RFCs RFC 155 Blueprint namespace enables user defined namespace using an XML schema file. In this RFC, a transaction custom namespace is introduced to allow users to easily declare transaction attribute within one or more methods of the blueprint bean component. RFC 166XXX blueprint bean interceptor can be used to allow blueprint container to intercept method invocation to add additional transactional demarcation operations before and after the method invocation. 5.2 Blueprint Transaction XML Schema By leveraging RFC 155, the following blueprint transaction XML schema is proposed for blueprint transaction: <?xml version="1.0" encoding="utf-8"> <xsd:schema xmlns=" xmlns:xsd=" targetnamespace=" elementformdefault="qualified" attributeformdefault="unqualified" version="1.0.0"> <xsd:annotation> <xsd:documentation> <![CDATA[ Copyright OSGi Alliance 2010

255 Blueprint Declarative Transaction Page 8 of 17 Draft November 16, 2010 This is the XML Schema for the OSGi Blueprint declarative transaction development descriptor. Blueprint declarative transaction is a custom namespace for OSGi Blueprint service development descriptor. It is designed to decorate transaction attribute of the bean components, which can be done at the bean level or at the bundle wide level. In other words, the transaction element can reside in the bean element or in the root of the blueprint element as a top level transaction element. Blueprint configuration files using this schema must indicate the schema using the transactions/v1.0.0 namespace. For example, <transaction xmlns=" if used as a qualified namespace, "tx" is the recommended namespace prefix. ]]> </xsd:documentation> </xsd:annotation> <xsd:simpletype name="ttransactionattribute"> <xsd:annotation> <xsd:documentation> <![CDATA[ The TtransactionAttribute type defines the transaction attribute for blueprint declarative transaction. ]]> </xsd:documentation> </xsd:annotation> <xsd:restriction base="xsd:string"> <xsd:enumeration value="required" /> <xsd:enumeration value="mandatory" /> <xsd:enumeration value="requiresnew" /> <xsd:enumeration value="supports" /> <xsd:enumeration value="notsupported" /> <xsd:enumeration value="never" /> </xsd:restriction> </xsd:simpletype> <xsd:complextype name="ttransaction"> <xsd:annotation> <xsd:documentation> <![CDATA[ Ttransaction defines one or more methods that are intercepted with the specified transaction attribute. Multiple methods names can be wildcarded with a '*'. Method can be a mixture of fixed string and one wild- Copyright OSGi Alliance 2010

256 Blueprint Declarative Transaction Page 9 of 17 Draft November 16, 2010 card. Methods can be whitespace or comma separated. The bean attribute refers to the bean component id and can only be used for top level transaction element. Similar as methods, beans can be whitespace separated and be a mixture of fixed string and one wild-card. ]]> </xsd:documentation> </xsd:annotation> <xsd:attribute name="method" type="xsd:string" /> <xsd:attribute name="value" type="ttransactionattribute" use="optional" default="required" "required" /> <xsd:attribute name="bean" type="xsd:string" /> </xsd:complextype> <xsd:element name="transaction" type="ttransaction"> <xsd:annotation> <xsd:documentation> <![CDATA[ The <transaction> element is the root element for blueprint declarative transaction ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:schema> When the tx element is not specified in the blueprint XML definition file, the default behavior is equivalent to: <tx:transaction value="notsupported" /> The Transaction Element The transaction element can be used as a child of the bean element to specify the bean level transaction configuration for the bean. The transaction element can also be used at the top level (e.g. at the root of the blueprint element) to specify the bundle wide transaction for the blueprint managed bundle. The following must be used from high priority to low priority to determine which transaction attributes apply to a particular method in a bean component: 1. bean level transaction element with the method attribute. 2. bean level transaction element without the method attribute. 3. top level transaction element with both the bean attribute and method attribute Copyright OSGi Alliance 2010

257 Blueprint Declarative Transaction Page 10 of top level transaction element with only the bean attribute 5. top level transaction element with only the method attribute Draft November 16, top level transaction elements with no bean or method attribute specified When using the above selection rules, if the bean attribute or method attribute is set to '*', it must be treated as the attribute is not specified. The top level transaction elements should not apply to synthetic beans. If there are potential multiple matches for bean level transaction, the transaction namespace handler must throw a n Exception Throwable back to the Blueprint Container to fail the creation of the Blueprint Container. If there are multiple matches for bundle wide transaction, the transaction namespace handler must throw an Exception Throwable back to the Blueprint Container to fail the creation of the Blueprint Container. The Blueprint FAILURE event must be emitted as the result of the failure, which is specified in the Blueprint Container Specification The Method Attribute The method attribute is used to specify one or more method names and method names can be wild-carded with one '*'. '*' can appear anywhere in the name and can only appear once. Methods can be listed (whitespace or comma separated) and be a mixture of fixed string and one wild-card. If there are potential multiple matches, the transaction namespace handler must throw a Throwablen Exception back to the Blueprint Container to fail the creation of the Blueprint Container. For example, when the transaction name space handler parses the 2 nd transaction element inside the bean, it detects multiple matching for potential methods like count1row thus the name space handler must throw a Throwable back to the Blueprint Container to fail the creation of the Blueprint Container for the bundle. <bean...> <tx:transaction method="count*" value="required" /> <tx:transaction method="count*row" value="requiresnew" /> </bean> The method attribute is optional. When the method attribute is not being specified, set to '*', it is equivalent to method attribute set to '*'not being specified.. For example: <bean...> <tx:transaction method="*" value="required" /> </bean> The Transaction Attribute The transaction attributes(required, Mandatory, RequiresNew, Supports, NotSupported, and Never) are defined in Enterprise Java Bean3.0 specification section The Blueprint container will manage transaction boundaries in the same manner defined for the EJB Copyright OSGi Alliance 2010

258 Blueprint Declarative Transaction Page 11 of 17 Draft November 16, 2010 container, which is not repeated here. After parsing the blueprint XML definition file, the blueprint container must demarcate transactions based on the transaction attribute specified in the blueprint XML definition file The Bean Attribute The bean attribute can only be specified in top level transaction element. It is used to specify one or more bean component ids and beans can be wild-carded with one '*'. '*' can appear anywhere in the name and can only appear once. Beans can be listed (whitespace or comma separated) and be a mixture of fixed string and wild-card. The bean attribute is optional. When the bean attribute is not specified, the default value is an asterisk character (*). For example: <blueprint> <tx:transaction method="insert*" value="required" /> </blueprint> <Maybe a requirement for blueprint name space handler..> When the blueprint container parser parses the blueprint XML definition files, it is recommended to parse the blueprint elements first before any of the blueprint custom elements like transaction element. The blueprint namespace handler design must provide a way to allow the transaction namespace handler to perform post blueprint namespace processing. This ensures all blueprint components are registered in the Component Definition Registry when the transaction namespace handler parses the bundle wide transaction elements and uses the Component Definition Registry to validate the bean attribute. which the transaction namespace handler can use to valid the bean attribute when parsing the bundle wide transaction elements Transaction Examples At Bean Level Transactions can be configured at the bean level. You must specify the value attribute in the transaction element. Valid values are those that are defined by Java EE, that is, Required, RequiresNew, NotSupported, Mandatory, Supports or Never. For example: <bean...> <tx:transaction method="updateorder" value="required" /> </bean> You can also use the wildcard character anywhere in a method name and but you can only use it once.you can use it multiple times. For example: <bean...> <tx:transaction method="update*ord*" value="required" /> </bean> Methods can be listed (whitespace or comma separated) and be a mixture of fixed string and wild-cards, for example, Copyright OSGi Alliance 2010

259 Blueprint Declarative Transaction Page 12 of 17 Draft November 16, 2010 <bean...> <tx:transaction method="update* makeitso" value="required" /> </bean> Multiple method configurations can appear in the same component, for example <bean...> <tx:transaction method="update* makeitso" value="required" /> <tx:transaction method="recordstatus" value="requiresnew" /> </bean> Method configurations can appear alongside one component configuration, where the methods config takes precedence. <bean...> <tx:transaction value="required" /> <tx:transaction method="recordstatus" value="requiresnew" /> </bean> Wildcard matching and selection behavior is determined by the rules specified in section Transaction Examples At Bundle Wide Level Transactions can be configured at the bundle wide level. Same as bean level configuration, you must specify the value attribute in the transaction element, for example: <blueprint> <tx:transaction value="required" />... </blueprint> You can also use the wildcard character anywhere in a method name or a bean name butand you can use the wildcard character multiple timesonly once. For example: <blueprint> <tx:transaction bean="bean1*" method="update*ord*" value="required" />... </blueprint> Methods or Beans can be listed (whitespace or comma separated) and be a mixture of fixed string and wild-cards, for example, <blueprint> <tx:transaction bean="bean1* bean2*" method="update* makeitso" value="required" />... </blueprint> Copyright OSGi Alliance 2010

260 Blueprint Declarative Transaction Page 13 of 17 Draft November 16, 2010 Multiple configurations can appear in the same bundle, for example <blueprint> <tx:transaction method="update* makeitso" value="required" /> <tx:transaction bean="bean1" bean="update*" value="requiresnew" /> </blueprint> When multiple configurations exist, the selection behavior is determined by the rules in section Transaction Examples At Bean Level And Bundle Wide Level Transaction can be configured at bean level, bundle wide level or both. <blueprint> <tx:transaction value="required" /> <tx:transaction method="get*" value="supports" /> <tx:transaction bean="notx" value="never" /> <tx:transaction bean="sometx" method="get*" value="mandatory" /> <bean id="requiresnew" class="foo"> <tx:transaction value="requiresnew"/> </bean> <bean id="notx" class="foo"/> <bean id="sometx" class="foo"/> <bean id="anotherbean" class="foo"/> <blueprint/> In the above example the following would apply: For the bean requiresnew, all methods have REQUIRESNEW behaviour. For the bean notx, all methods have NEVER behaviour. For the bean sometx, methods starting with "get" are MANDATORY, and all other methods are REQUIRED. Copyright OSGi Alliance 2010

261 Blueprint Declarative Transaction Page 14 of 17 Draft November 16, 2010 For the bean anotherbean, all methods that start with "get" are SUPPORTS, and all other methods are REQUIRED. 5.3 Sample User Scenario Continuing to use the example in the section 2, the following defines the single bean called TestBeanImpl, using the declarative transaction on the method insertrow with transaction attribute value required. blueprint.xml <?xml version="1.0" encoding="utf-8"?> <blueprint xmlns=" xmlns:tx=" <bean id="testbeanimpl" class="org.apache.aries.simple.testbeanimpl"> <tx:transaction method="insertrow" value="required"/> </bean> </blueprint> The TestBeanImpl.java example used in section 2 can be simplified as below: TestBeanImpl.java public class TestBeanImpl { } public TestBeanImpl() {... } public void insertrow(string name, int value) throws SQLException { // start the operation to insert name, value into the db... } Based on the application's requirement, application developers can set different transaction attributes on specific methods, such as Required, RequiresNew, Mandatory, NotSupported, Supports, and Never. This simplifies greatly the transaction management in application code TestBeanImpl.java. Copyright OSGi Alliance 2010

262 Blueprint Declarative Transaction Page 15 of 17 Draft November 16, Command Line API None 7 JMX API RFC 139 describes the JMX API to the OSGi Framework and a number of standard OSGi Services. The JMX specification is also present as chapter 124 in the OSGi spec documents. For all new functionality added to the OSGi Framework the question should be asked: would this feature benefit from a JMX API? The expectation is that in most cases it would. The JMX API for the design in this RFC should be described here and if there is no JMX API an explanation should be given explaining why this is not applicable in this case. None 8 Initial Spec Chapter Provide a link to where the Initial Spec Chapter can be found. The Initial Spec Chapter is typically written by someone other than the author(s) of this RFC and represents a rewrite of this document as close as possible to what will ultimately appear in the OSGi Specifications. It will be used by the Specification Editor as the basis for the ultimate specification chapter. The spec template and writing guidelines can be found here: Copyright OSGi Alliance 2010

263 Blueprint Declarative Transaction Page 16 of 17 Draft November 16, Considered Alternatives For posterity, record the design alternatives that were considered but rejected along with the reason for rejection. This is especially important for external/earlier solutions that were deemed not applicable. 10 Security Considerations Description of all known vulnerabilities this may either introduce or address as well as scenarios of how the weaknesses could be circumvented. 11 Document Support 11.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. EJB specification v Add references simply by adding new items. You can then cross-refer to them by chosing <Insert><Cross Reference><Numbered Item> and then selecting the paragraph. STATIC REFERENCES (I.E. BODGED) ARE NOT ACCEPTABLE, SOMEONE WILL HAVE TO UPDATE THEM LATER, SO DO IT PROPERLY NOW Author s Address Copyright OSGi Alliance 2010

264 Blueprint Declarative Transaction Page 17 of 17 Draft November 16, 2010 Name Company Lin Sun IBM Address 3039 Cornwallis Road, RTP, NC, Voice Name Company Address Voice Ian Robinson IBM IBM UK Ltd, MP211, Hursley Park Road, Winchester, SO21 2JN Acronyms and Abbreviations 11.3 End of Document Copyright OSGi Alliance 2010

265 RFC Blueprint Bean Interceptors Draft 15 Pages Abstract This RFC describes the requirements and solution for Blueprint Bean Interceptors as an extension of the Blueprint container specification. Copyright IBM 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

266 RFC Blueprint Bean Interceptors Page 2 of 15 Draft November 24, Document Information 0.1 Table of Contents 0 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Overview Example using Declarative Transaction Support Problem Description Requirements Technical Solution Namespace Handler Associating Interceptors with Beans Registering Interceptors Using bean-id for identification in Interceptor Service Registration Locating and Ordering Interceptors Summary of Namespace Handler requirements The Interceptor Interface Processing Interceptors Ordering Interceptors (Rank) Error processing for Interceptors Correlating pre/post/exception Interceptor calls Interceptor Lifecycle Command Line API JMX API Initial Spec Chapter Considered Alternatives Bytecode Weaving required implementation Security Considerations Copyright IBM 2010 `

267 RFC Blueprint Bean Interceptors Page 3 of 15 Draft November 24, Document Support References Author s Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in Source code is shown in this typeface. 0.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial 09/07/10 Initial version Joe Bohn, IBM, [email protected] with input from: Graham Charters, IBM, [email protected] Andrew James Osborne, IBM, [email protected] /08/10 Removed references to Interceptors being services in Command Line API and JMX API sections /12/10 Updates based upon discussions from 9/8/10 EEG meeting and 9/17/10 F2F meetings: Register Interceptors are Services per bean/bundle Add service references (optional or mandatory) for interceptor services use Service Ranking to order interceptors Require that all bean managers provide a unique bean-id, even for inline or anonymous beans. Lifecycle of Interceptor tied to lifecycle of Namespace Handler Copyright IBM 2010 `

268 RFC Blueprint Bean Interceptors Page 4 of 15 Draft November 24, 2010 Revision Date Comments /24/10 Minor changes based upon discussion at Walldorf clarify service rank order clarify Namespace Handler requirements clarify base blueprint requirement requirement regarding beanid for inner/anonymous beans. Clarify URI parameter requirement for interceptor service property. 1 Introduction RFP 137 [8]. was approved defining requirements for Blueprint Bean Interceptors. This RFC describes a proposal to meet those requirements. A slightly modified version of the introduction from the RFP is included next in this introduction for convenience. The Blueprint Container specification version 1.0 in OSGi Compendium Release 4.2 defines a dependency injection framework for OSGi bundles that supports the unique dynamic nature of beans and services. Bundles in this programming model contain a number of XML definition resources which are used by the Blueprint Container to wire the application together and start it when the bundle becomes active. A proposed extension to the Blueprint Container Specification is the Blueprint Declarative Transaction feature [4]. One of the necessary capabilities of the Blueprint Declarative Transaction feature is a mechanism to intercept a Blueprint Bean method invocation to add logic for transaction management. The same capability to intercept a blueprint bean method invocation and perform some function can also be useful for other features on Blueprint bean definitions that leverage Blueprint Namespace [3]. and require some runtime capability when processing blueprint bean methods. This RFC refines the requirements and describes a solution for Blueprint Bean Interceptors as an extension of the Blueprint Container Specification. Note that this RFC will be developed in conjunction with the Blueprint Declarative Transactions [4]. and Blueprint Namespaces [3]. RFCs. This RFC may be leveraged to fulfill the capabilities defined in the Blueprint Declarative Transactions design and may propose additional requirements for the Blueprint Namespaces design. Copyright IBM 2010 `

269 RFC Blueprint Bean Interceptors Page 5 of 15 Draft November 24, Application Domain 2.1 Overview The Blueprint Container manages the creation and life cycle of blueprint beans. The Blueprint Namespace extension allows for the introduction of custom components or additional features on standard blueprint components. Blueprint Namespace extensions can be applied to bean definitions as well as other components. When applied to bean definitions, a namespace handler can be used to enhance a blueprint bean definition or inject properties into the bean. As such, the Blueprint specification and namespace extensions are primarily concerned with the creation of blueprint beans. However, with the current capabilities they could not be involved in subsequent method invocation against the bean. When introducing custom features for a blueprint bean there are times when it may be necessary to enhance the functionality of the bean during execution and perhaps on a per-method invocation basis. For example, to support capabilities such as those required by Blueprint Declarative Transactions it is necessary to gain access into the flow of control before and after a bean method invocation. Blueprint Declarative Transactions requires this access to facilitate transaction management. Therefore, a solution for Blueprint Bean Interceptors requires some mechanism to extend a bean by permitting logic to be injected prior to and immediately after a bean method invocation. It seems reasonable that such an extension would always be associated with a comparable extension in the blueprint bean component definition which is currently accomplished using the Blueprint Namespace extension. Therefore, it seems reasonable that a Blueprint Bean Interceptor would be associated with a Blueprint Namespace and should be introduced into the system by the namespace handler. It should therefore be possible to support the implementation of Blueprint Bean Interceptors using Namespace Handlers. However, this should not preclude possible future extension mechanisms such as Annotations which may also provide similar capabilities to extend a blueprint bean component definition and therefore could also introduce and support blueprint bean interceptors. 2.2 Example using Declarative Transaction Support As mentioned earlier the Declarative Transaction Support that is currently being proposed (see [4].) has a need to intercept bean methods. One possible implementation for this capability would be to use Blueprint Bean Interceptors as defined in this RFC. In addition to the Transaction Namespace Handler required to parse the custom namespace a blueprint bean interceptor could also be created. The interceptor includes logic that is processed before a bean method invocation (pre-call), and after a method invocation (post-call). In such a scenario, a declarative transaction namespace entry is applied to the blueprint bean definition in the XML configuration file. The namespace handler is invoked when parsing the XML configuration file. At this point it is important to be able to associate the interceptor with the bean definition. This interceptor can then be retreived when the bean definition is being interpreted by the Bean Manager. When the blueprint bean is later instantiated, the associated interceptor(s) is bound to the bean (possibly using a proxy) such that the appropriate interceptor logic can be invoked before and/or after the bean method invocation. For Blueprint Declarative Transaction support, the logic creates any necessary transactions prior to the bean method call and commits or rolls-back those transactions following the method call as necessary for the method result. A unique method correlator is also required to match processing before the method invocation (pre-call) with logic Copyright IBM 2010 `

270 RFC Blueprint Bean Interceptors Page 6 of 15 Draft November 24, 2010 after the method invocation (post-call). In the case of Blueprint Declarative Transactions this correlator is used to match the transaction created in the pre-call with its response for commit or rollback in the post-call. Given that there could be more than one interceptor associated with a particular bean, and that the processing of one interceptor could have some impact on the processing of another interceptor, some mechanism must be provided to ensure a deterministic order in invocation of interceptors for a given bean method pre-call and postcall. It is intended that the bean interceptor capability is used in conjunction with Blueprint Namespaces as an optional feature when blueprint bean method level enhancement is also a requirement. 3 Problem Description A Blueprint Namespace extension to a bean definition may require some logic that must be invoked in conjunction with a blueprint bean method invocation. As already discussed, this is the case with Blueprint Declarative Transactions to support the creation of a transaction prior to invoking methods on a bean and close the transaction following the bean method invocation. Declarative Transactions uses a Blueprint Namespace extension to declare the level of transaction support required for the blueprint bean methods (see [4]. for details). Without a feature such as Blueprint Bean Interceptors there is no solution to intercept the bean method invocations to begin, commit, or rollback a transaction. This proposal is to provide a mechanism to define, register, and invoke interceptors before and after bean method invocations when appropriately specified in the Blueprint XML for the associated namespace or similar extension mechanism. The extension mechanism could then register an interceptor for the bean that would perform necessary functionality for the namespace. 4 Requirements 1. Blueprint Bean Interceptors MUST support interceptor invocation prior to a bean method call (pre-call) with the access to component metadata and all facets of the method necessary for successful pre-call processing (such as method name, parameters, etc...) 2. Blueprint Bean Interceptors MUST support a unique method invocation correlator that can be used to match a method pre-call with subsequent post-call results. Copyright IBM 2010 `

271 RFC Blueprint Bean Interceptors Page 7 of 15 Draft November 24, Blueprint Bean Interceptors MUST support interceptor invocation following a successful bean method call with access to component metadata and all facets of the method necessary for successful post-call processing (such as method name, parameters, correlator, result, etc..). 4. Blueprint Bean Interceptors MUST support interceptor invocation following an exception result to a method call with access to component metadata and all facets of the method necessary for successful post-call exception processing (such as method name, parameters, correlator, exception, etc...). 5. Blueprint Bean Interceptors MUST provide a mechanism to support deterministic ordering (relative rank) of interceptor invocation pre-call and post-call in the event that more than one interceptor is registered for a given bean method. 6. It MUST be possible to implement RFP 138 Declarative Transactions in terms of a Blueprint Bean Interceptor but it is not a requirement that Declarative Transactions leverage this capability. 7. Blueprint Bean Interceptors MUST NOT interfere with the normal flow of control for a bean which is not defined to utilize this capability. 8. It MUST be possible to implement Blueprint Bean Interceptors using RFC 155 Namespace Handlers[3]. 5 Technical Solution To implement a Bean Interceptor there are several primary tasks that must be considered. First, one must define the structure and behavior of a Blueprint Bean Interceptor itself. Second, one must define some mechanism to associate one or more Bean Interceptors with particular Blueprint Beans. Finally, one must define a mechanism for invoking the appropriate Interceptor methods in conjunction with calls to the Blueprint Bean methods. A slightly more detailed list of the items that must be supported in a Blueprint Bean Interceptor solution follows: 1. Create a mechanism to associate Interceptors with Blueprint Bean definitions (we will use custom Namespaces). 2. Define a standard interface that Interceptors can implement (the Interceptor interface) 3. Define a mechanism for the Blueprint Bean Manager to locate and invoke Interceptors for Blueprint Bean method invocations. 4. Define a mechanism to order the processing of multiple Blueprint Bean Interceptor invocations. 5. Define a mechanism to deal with potential errors produced by a Blueprint Bean Interceptor implementation. 6. Define a mechanism to correlate pre-method invocations with post-method or error results. Copyright IBM 2010 `

272 RFC Blueprint Bean Interceptors Page 8 of 15 Draft November 24, Namespace Handler Associating Interceptors with Beans As mentioned above, the first primary task is to associate the Interceptors with the designated Beans. At this point in time Namespace Handlers are the primary mechanism for customization and so this design will be in terms of customization using Namespace Handlers. However, additional mechanisms of customization may be introduced in the future such as custom annotations. When such mechanisms are introduced they may also provide an appropriate mechanism to associate bean interceptors with specific bean definitions. Namespace handlers are a natural mechanism to use for introducing Interceptors. In fact, it is difficult to conceive of a scenario where an interceptor would be required without some corresponding metadata extensions. For example, the capabilities required for Declarative Transactions require not only the introduction of a custom Namespace to associate the feature with a bean but also the runtime capability provided by Blueprint Bean interceptors to act on the method level. In the case of Declarative Transaction support the Namespace Handler has a need to allocate a transaction at the start of certain methods and commit or rollback that transaction based upon the results from the bean method. At the same time the Namespace is necessary to define the criteria applied the transaction Registering Interceptors A Namespace Handler must first obtain a reference to the Interceptor. The Interceptor itself, it is simply a POJO that implements the Interceptor interface. The interface specifies the various methods that must be supported to participate as a Blueprint Bean Interceptor. The interceptor implementation can be created within the Namespace Handler itself or it can be created by the Blueprint Container and injected into the Namespace handler similar to any other java object. Next, the Interceptor must be associated with the Blueprint Bean metadata. This RFC proposes that this is accomplished by registering a service in the Service Registry for the interceptor using the bundle-id of the bundle being parsed, the bean-id for the associated bean, and the URI for the specific Namespace as properties on the service. The Interceptor service should also be registered as implementing the the Interceptor interface (see seciont 5.2 ). The set of service properties that should be advertised on the Interceptor when registered are as follows: osgi.service.blueprint.bean-id = the bean-id as specified in the blueprint plan or generated by the blueprint container. osgi.service.blueprint.bundle-id = the bundle-id for the blueprint bundle that is being parsed osgi.service.blueprint.namespace = the URI for the Namespace handler registering this Interceptor in the Service Registry. In the event that the Namespace handler supports multiple URIs the namespace handler should chose just one for registration with the interceptor service. The URI only serves to differentiate this interceptor service from other interceptor services that apply to the same bean instance. Finally, there needs to be some association between the bundle being parsed that requires this interceptor and the service registered for the interceptor. This is accomplished by the Namespace handler creating a Service Reference and adding it to the component definitions for the bundle being parse. The Service Reference can be either mandatory or optional depending on the required availability of this interceptor. Note, at this time interceptors are only being proposed for Blueprint Beans and hence it is expected that interceptors will only be registered against Blueprint Bean components. However, this should not be presumed in an implementation. Future enhancements or extensions may find it useful to also registered Interceptors against Copyright IBM 2010 `

273 RFC Blueprint Bean Interceptors Page 9 of 15 Draft November 24, 2010 other component types and therefore any implementation specifically created for a Blueprint Bean component should gracefully ignore any registration or invocation for a different component type Using bean-id for identification in Interceptor Service Registration The use of fact the bean-id along with bundle-id and namespace when registering an interceptor service has a significant implication. It implies that bean-id must be available for any bean that a namespace handler may desire to attach an interceptor, including anonymous and inner beans. Therefore, it is proposed by this RFC that the blueprint specification is changedto require so that it no longer requires that ComponentMetadata.getId() to returns null for inlined and anonymous bean managers and in fact requires that all bean managers return a unique bean id within the Blueprint Container Locating and Ordering Interceptors The purpose of registering an interceptor with a bean is to enable it to be later retrieved and invoked. Therefore it is necessary to have some means to retrieve the interceptor reference. Also, because multiple interceptors can be registered for the same bean definition, it must be possible that multiple interceptors are applicable for a given bean and they must be invoked in some deterministic order. To accomplish this interceptors are ranked using the rank of the service registered for the interceptor. Interceptors are ordered by descending rank in a manner consistent with Services. In the event of a tie by rank the order of registration is used. In other words, priority is given to the highest ranked interceptors and the earliest registered interceptors. The retrieval of interceptors is performed by Blueprint Bean Manager when instantiating a bean. The Bean Manager must leverage the service references to locate applicable interceptors for the specified bean, honoring the service reference availability of mandatory or optional and honoring the service rank to process interceptors in the appropriate order. If an interceptor service reference is mandatory then an exception should be thrown is the required interceptor service is unavailable for some reason. If the interceptor service reference is optional an unavailable service reference should be ignored by the Blueprint Bean Manager Summary of Namespace Handler requirements Register an interceptor service for each bean instance in the service registry using the bundle context of the namespace handler for each bean instance that requires runtime enhancement. Create mandatory or optional service references added to the component definitions for the bundle being parsed for each interceptor services registered for a bean by this namespace handler. 5.2 The Interceptor Interface All interceptors must implement the common interface to provide for pre, post, and error Interceptor processing on a bean method invocation. The proposed API for Interceptor is as follows: /** * An Interceptor interface provides support for custom interceptor implementation. */ public interface Interceptor { /** * This is called just before the method m is invocation. cm : the component's metada m: the method to be invoked Copyright IBM 2010 `

274 RFC Blueprint Bean Interceptors Page 10 of 15 Draft November 24, 2010 parameters: method parameters correlator which will subsequently be passed to postcall* Throwable */ public Object precall(componentmetadata cm, Method m, Object... parameters) throws Throwable; /** * This method is called after the method m is invoked and returned normally. cm: the component metadata m: the method invoked returntype : the return object precallcorrelator correlator returned by precall Throwable */ public void postcallwithreturn(componentmetadata cm, Method m, Object returntype, Object precallcorrelator) throws Throwable; /** * The method is called after the method m is invoked and causes an exception. cm : the component metadata m : the method invoked ex : the <code>throwable</code> thrown precallcorrelator correlator returned by precall Throwable */ public void postcallwithexception(componentmetadata cm, Method m, Throwable ex, Object precallcorrelator) throws Throwable; } 5.3 Processing Interceptors It is the responsibility of the Blueprint Bean Manager to locate and manage the interceptors as associated with Blueprint Beans. The Blueprint Bean Manager is also responsible to construct Blueprint Bean instances. The Blueprint Bean Manager must therefore ensure that it constructs Bean instances that will honor the Interceptors that have been defined. This would involve the following steps: 1. Interrogating component definitions for service references that registered with the Interceptor interface for this bean. 2. Construct an instance of the Bean in such a way that future invocations of methods on the bean will invoke the Interceptors that have been defined. 3. Invoking the interceptors on each method invocation. The mechanisms used to instantiate Blueprint Beans are not prescribed in the Blueprint Container RFC [5]. using specific objects and are therefore left as an internal implementation detail of a Blueprint Bean Manager. Therefore, this RFC will not call out explicit constructs or mechanisms (such as a BeanRecipe) that should be involved in the interrogation of the interceptors or construction of a bean that will honor the intention of the interceptors. This RFC will simply specify the expected behavior and assume that this is implemented by the Bean Manager as appropriate. However, one possible mechanism that can be employed would be to allocate a proxy Copyright IBM 2010 `

275 RFC Blueprint Bean Interceptors Page 11 of 15 Draft November 24, 2010 object for the bean that would defer to the interceptors before and after each method call against the Bean. 4. If multiple interceptors are associated with a bean they must be invoked in the order specified by the rank specified in the Service for the interceptor. The processing should invoke the highest ranked interceptor precall method and add the knowledge of that interceptor and returned correlator to a logical stack for later use with the Bean method returns. Processing should then continue with the next highest interceptor until all interceptor precall methods have been invoked. The bean's method should then be invoked. When processing the result of the bean method (either the return value or exception) interceptors would be removed from the logical stack to process the appropriate postcall* method. This will effectively invoke the postcall* methods in reverse order from the precall methods as interceptors are removed from the stack and provide symmetry on the calls. 5. Care must be taken to preserve the correlator returned from the precall Interceptor method invocations so that they can be passed into the appropriate postcall* method invocation after the Bean method completes. 6. Any exceptions returned from an Interceptor precall or postcall* method should be logged and interrupt program flow. (see 5.5 ). 7. Interceptors should not modify the method, parameters, results or exceptions provided to or returned by a Blueprint Bean method invocation. These parameters are only provided to the interceptor for reference. Introducing a solution to protect the bean data is recommended but not required. The only case where it is appropriate to make any change is if the Interceptor itself has a need to thrown an exception during processing in which case it may override a bean method exception (see 5.5). 5.4 Ordering Interceptors (Rank) Order of Interceptors is determined by the self defined rank provided by the Namespace Handler when the Interceptor Service is registered. The rank is defined as a simple integer and is processed from highest to lowest. In the event of multiple Interceptors with the same rank the order is based upon the order of registration which is evident using the service id. The service with the lower service id was registered earlier (see section of OSGi core specification R4V42). Multiple interceptors associated with a single bean must be processed in order by rank and placed in a logical stack for processing. This is to provide symmetry for interceptor processing. Therefore, if there are 2 interceptors prioritized as A and B the processing order would be the following: A.preCall B.preCall bean method invocation B.postCall* A.postCall* 5.5 Error processing for Interceptors There are cases where an interceptor may need thrown an exception. This is an indication that an error has occurred in the interceptor and processing either cannot or should not continue. One potential use of this function by an Interceptor would be to block the bean itself and additional interceptors from being invoked. For example, a Copyright IBM 2010 `

276 RFC Blueprint Bean Interceptors Page 12 of 15 Draft November 24, 2010 validation interceptor may have a need to block subsequent access to additional interceptors and the bean method if the appropriate credential was not present. Any exception thrown from within an Interceptor in the precall or postcall* processing should be treated as a termination condition. The exception should be logged, and re-thrown. An exception can be thrown from an Interceptor in the precall, postcallwithreturn, or postcallwithexception. 1. precall - In the event an exception is thrown by an Interceptor in a precall the bean method should not be invoked and all Interceptors that have not yet been processed should be ignored. The postcallwithexception methods of each interceptor that has already processed the precall should be executed in the correct order before the exception is propagated back to the caller. 2. postcallwithreturn - In the event an exception is thrown by an Interceptor in a postcallwithreturn method the exception should be propagated and all remaining Interceptors should be invoked in the appropriate order with the postcallwithexception method to indicate the error processing. 3. postcallwithexception In the event an exception is thrown by an Interceptor in the postcallwithexception method the exception should be propagated and all remaining Interceptors should be invoked in the appropriate order using the postcallwithexception method to indicate error processing. 4. If multiple exceptions are thrown from multiple Interceptors in multiple methods (precall or postcall*) the first exception thrown should be the one propagated back to the caller. The blueprint bean itself may also throw an exception. If this is the case, the exception should be propagated back to the caller if it is not a RuntimeException. In the case of a RuntimeException it should be returned to the caller if and only if an exception was not also thrown from an Interceptor while processing the postcallwithexception. Basically, an exception thrown by an Interceptor is considered of greater importance than a RuntimeException from the bean. 5.6 Correlating pre/post/exception Interceptor calls The precall method returns a correlator Object that can be used by the Interceptor to match precall and postcall* method invocations. The Object can be anything that is useful for the Interceptor and will simply be preserved and returned on matching methods. The Bean manager will ensure that a bean definition that includes interceptors will invoke the precall method on the associated interceptor(s) and save the correlator for subsequent processing with the same interceptor postcall* method. 5.7 Interceptor Lifecycle There is a high cohesion between an interceptor and the namespace handler that rquires the interceptor capability to fulfill it's purpose. It was considered if the Interceptor should be managed independently of the namespace handler. This seems to be an approach that would introduce a lot of complexity for very little benefit. Any changes in a namespace handler that leverages the interceptor support would most likely result in changes to the corresponding interceptor to react to schema or other changes in the namespace. Furthermore, it is unlikely that there would be changes in an underlying interceptor without corresponding changes in the namespace handler. Therefore, for the purposes of this design it is assumed that the lifecycle of an interceptor is consistent with the lifecycle of a namespace handler and most likely both will be delivered in the same bundle. Because the namespace handler is the primary element that registers and manages any associated interceptors it seems appropriate that lifecycle scenarios are primarily (and perhaps exclusively) driven from the namespace Copyright IBM 2010 `

277 RFC Blueprint Bean Interceptors Page 13 of 15 Draft November 24, 2010 handler. The namespace specification should address the issue of managing blueprint containers that have been extended by the namespace handler such that the blueprint bundle can be updated (perhaps re-parsed) if the namespace handler is updated. The creation, removal, or updating of associated interceptors via advertised interceptor services in the service registry and corresponding service references in the blueprint components would be managed by the namespace handler implementation following guidelines from the blueprint namespace handler specification. 6 Command Line API If this specification would benefit from a command line interface, describe it here. Commands should be realized as described in RFC 147. At this point in time we do not envision a command line API that corresponds to interceptors. 7 JMX API RFC 139 describes the JMX API to the OSGi Framework and a number of standard OSGi Services. The JMX specification is also present as chapter 124 in the OSGi spec documents. For all new functionality added to the OSGi Framework the question should be asked: would this feature benefit from a JMX API? The expectation is that in most cases it would. The JMX API for the design in this RFC should be described here and if there is no JMX API an explanation should be given explaining why this is not applicable in this case. At this point in time we do not envision an specific JMX APIs for Interceptors. 8 Initial Spec Chapter Provide a link to where the Initial Spec Chapter can be found. The Initial Spec Chapter is typically written by someone other than the author(s) of this RFC and represents a rewrite of this document as close as possible to Copyright IBM 2010 `

278 RFC Blueprint Bean Interceptors Page 14 of 15 Draft November 24, 2010 what will ultimately appear in the OSGi Specifications. It will be used by the Specification Editor as the basis for the ultimate specification chapter. The spec template and writing guidelines can be found here: Considered Alternatives For posterity, record the design alternatives that were considered but rejected along with the reason for rejection. This is especially important for external/earlier solutions that were deemed not applicable. 9.1 Bytecode Weaving required implementation Bytecode Weaving is another alternative that could be considered to implement Bean Interceptor capability. For details on Bytecode Weaving reference [6]. and [7]. There is nothing in this design that prohibits a Bytecode Weaving solution. A Bytecode weaving solution could be triggered by a Namespace Handler which could weave the interceptor logic into the specified bean. Mechanisms similar to those defined in this design would still be necessary to prioritize and coordinate the activities of multiple interceptors and maintain knowledge of them in the Component Definition Registry. At this point in time it appears that requiring a Bytecode weaving solution would not result in a simplified or vastly superior solution and would appear to bring more complexity into the design for little benefit. Therefore, a Bytecode Weaving approach was not pursued as the primary solution for this design. 10 Security Considerations Description of all known vulnerabilities this may either introduce or address as well as scenarios of how the weaknesses could be circumvented. Copyright IBM 2010 `

279 RFC Blueprint Bean Interceptors Page 15 of 15 Draft November 24, Document Support 11.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. RFC 155 Blueprint Namespaces is available in the OSGi Alliance subversion repository in rfcs/rfc0155/rfc-155-blueprint-namespaces.pdf. [4]. RFC 164 Blueprint Declarative Transaction is available in the OSGi Alliance subversion repository in rfcs/rfc0164/rfc-0164-blueprint_transaction.pdf. [5]. RFC 124 Blueprint Service is available in the OSGi Alliance subversion repository in rfcs/rfc0124/rfc- 124.pdf. [6]. RFP 139 Bytecode Weaving Requirements is available in the OSGi Alliance subversion repository in rfps/rfp-0139-bytecode-weaving.pdf [7]. RFC 159 Bytecode Weaving Design is available in the OSGi Alliance subversion repository in rfcs/rfc0159/rfc-159-bytecodeweaving.pdf. [8]. RFP 137 Blueprint Bean Interceptors Requirement is available in the OSGi Alliance subversion repository in rfps/rfp-0137-blueprint_bean_interceptors.pdf 11.2 Author s Address Name Company Joe Bohn IBM Address P O Box 12195, 196A/503/N231, 3039 Cornwallis Rd., Research Triangle Park NC Voice [email protected] 11.3 Acronyms and Abbreviations 11.4 End of Document Copyright IBM 2010 `

280 Residential Design Documents OSGi Service Platform Release 4 Version 4.3 Early Draft 3 Revision November OSGi Alliance.

281 RFC-140 Residential Management Tree Draft 48 Pages Abstract Different industries are interested in the application of OSGi for their business, in which remote management is a key issue. Telecom operators (both fixed and mobile ones), server managers, and automotive manufactures, etc. need solutions to remotely manage their instances of OSGi frameworks. The main problem with that need is that is very difficult to solve with a single solution, taking into account that the management protocols are many and different for the different industries. To achieve this goal, a management object model should be defined to expose OSGi framework manageable information through a management agent. Copyright NTT Corporation 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

282 RFC-140 Residential Management Tree Page 2 of 48 Draft 24 November Document Information 1.1 Table of Contents 1 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Problem Description Management agent making use of OSGi standardized Java interfaces Mobile specification approach Support for TR-069 notifications Limitations in the number of services available in the DMT Mapping TR-069 to the OMA-DM inspired DMT model Conclusion Requirements Technical Solution Legend Framework Object BundleState Object PackageState Object ServiceState Object Filters Object BundleResources Object Limitations Maximum and Minimum values of numeric parameters Future Work Considered Alternatives Security Considerations Document Support References Author's Address Acronyms and Abbreviations End of Document Copyright NTT Corporation 2010

283 1.2 Terminology and Document Conventions RFC-140 Residential Management Tree Page 3 of 48 Draft 24 November 2010 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in 9. Source code is shown in this typeface. 1.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial Sep Initial Draft 0.2 Oct nd Draft 0.3 Nov rd Draft 0.4 Jan th Draft 0.5 Feb th Draft Koya Mori, NTT Corporation, [email protected] Overall architecture is changed based on REG meeting and RFC-139 definition. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Definition tables for all nodes in Management Objects are added. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Revising tree architecture based on the discussion at the REG meeting. Filter format description is added. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Revising Bundles Object based on discussion at the REG meeting. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Copyright NTT Corporation 2010

284 RFC-140 Residential Management Tree Page 4 of 48 Draft 24 November 2010 Revision Date Comments 0.6 Mar th Draft 0.7 May th Draft 0.8 Jun th Draft 1.0 Sep th Draft 1.1 Oct th Draft Revising Filters Object specification based on discussion and analysis. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Revising Resources sub-tree and Filters Object specification based on discussion at the REG meeting. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Revising wording and ServiceState Object specification based on discussion at the REG meeting. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Bundle StartLevel configuration is moved to the Framework Object. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Lifecycle sub-tree of Bundle is moved ti the Framework Object. Revising BundleState Object specification and BundleResources Object specification based on discussion at the REG meeting. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Copyright NTT Corporation 2010

285 RFC-140 Residential Management Tree Page 5 of 48 Draft 24 November 2010 Revision Date Comments 1.2 Jan th Draft 1.3 Feb th Draft 1.4 Apl th Draft 1.5 May th Draft 1.6 Aug th Draft Revising example of the Filter and TargetSubtree (Case1 and Case4). Declaring Residential management tree Data plug-in root path. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Revising BundleState Object and PackageState Object, ServiceState Object. Adding NumberOfEntries nodes below the $/OSGi/<instance-id>/. Moving Filters Object and Local node to below the $/OSGi/<instanceid>/. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Revising Certificate information format section and Service Property Dictionary nodes section based on discussion at the REG meeting. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Removing Policy Object and Configuration Object based on discussion at the Conference Call at May 12. Shigekuni Kondo, NTT Corporation, [email protected] Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Revising all section based on discussion at the REG F2F meeting in Gerona. Shigekuni Kondo, NTT Corporation, [email protected] Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Copyright NTT Corporation 2010

286 RFC-140 Residential Management Tree Page 6 of 48 Draft 24 November 2010 Revision Date Comments 1.7 Sep th Draft 1.8 Oct th Draft 1.9 Nov th Draft Revising Framework Object, BundleState Object, Filter Object and BundleResource Object based on comments for Ver Shigekuni Kondo, NTT Corporation, [email protected] Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Revising Framework Object, BundleState Object based on comments for Ver Shigekuni Kondo, NTT Corporation, [email protected] Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Revising Framework Object and Filters Object based on comments for Ver. 1.8 and agreements in F2F meeting in Heidelberg. Shigekuni Kondo, NTT Corporation, [email protected] Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] 2 Introduction Traditionally, fixed telecommunication operators don t have knowledge about what runs in the customer's local area network (LAN). They provide connectivity and manage the wide area network (WAN) that provides this connectivity, but they do not know anything about the devices and networks behind the gateway (xdsl mainly) that interconnect WAN and LAN. Recently the need for management of customer networks and devices is increasing in order to make the deployment of new complex services at home (home automation, tele-health, VoIP, IPTV, surveillance, etc) feasible with reasonable costs. For example to avoid sending technicians to the customer premises for solving problems. There are two main kinds of devices that need to be managed remotely in operator s business: those which come from the fixed line business managed via the TR-069 protocol, that is standardized by the Broadband FORUM [6], Copyright NTT Corporation 2010

287 RFC-140 Residential Management Tree Page 7 of 48 Draft 24 November 2010 and those which come from the mobile business managed by OMA DM, which is standardized by the Open Mobile Alliance. Up to now, the OSGi specifications cover the OMA DM ones, but lacks of specification about how an OSGi framework on a device could be managed by TR-069. One key question is: why do we need two technologies to manage devices in a converged scenario in which the two kinds of devices are going to interact between them? The question has a better answer from the business point of view than from a technical point of view. Fixed and mobile businesses have evolved independently during the last years. Both technologies have acquired enough critical mass not only for having success in product implementation and roll-out, but also to be a de facto standard in their respective applications domains. Despite the fact that the best solution would be a single protocol to manage all kind of devices, we are aware that at least for the short-medium term both technologies must coexist. For the future, the model shouldn t be closed to add new solutions, for example a mixed model that unifies both worlds. 3 Application Domain Driven by triple play service delivery in the home network, fixed line access service providers have the need to configure home devices to ensure the proper service delivery. Broadband Forum s CPE WAN Management Protocol (CWMP, alias TR-069) enables them to do this. By using a remote management server (Auto Configuration Server, ACS), they are able to manage TR-069 enabled devices. TR-069 provides them with possibilities to configure parameters, be informed of parameter changes (notification), start diagnostic tools, update firmware, etc. Similarly, for the mobile world, the OMA defined the OMA-Device Management specification for remote management of mobile devices. OMA-DM offers similar tools to the mobile service providers as TR-069 to fixed line service provider, but OMA-DM is of course tailored to the specifics of the mobile environment. As OSGi technology offers a flexible software environment for all these different devices, the remote management of the platform is of interest for both fixed and mobile service providers. As such, it should be possible to integrate the remote management of the OSGi platform, and the applications running on top of it, in the existing management infrastructure. The DMT Admin service with its mobile management tree in the Mobile specification for OSGi R4 standardizes the remote management of an OSGi platform. As it is largely inspired by OMA-DM, it needs to be evaluated for multi protocol support. Copyright NTT Corporation 2010

288 RFC-140 Residential Management Tree Page 8 of 48 Draft 24 November Problem Description In a scenario in which service providers offer a growing number of services, to use specific solutions for the management of those services is not the most suitable option. To speed up the deployment of these services, such as triple play, home automation or tele-health, it is essential to offer general management solutions that allow for the management of a large number of services and the flexible life-cycle management of applications. These devices usually are already managed by a standard protocol, so it makes sense that an OSGi framework, which hosts the services, running on a device could be managed in the same way as the other resources of the device. Of course, the remote management should be fully integrated in the existing remote management solutions of the service provider to avoid duplicating management infrastructure and to increase performance on the devices. Currently, there are two options in OSGi for remote management: create a management agent bundle making use of the Java object interfaces, create a protocol adapter bundle that interacts with the DMT Admin service, as defined in the OSGi Mobile specification. 4.1 Management agent making use of OSGi standardized Java interfaces Currently, for the management of a bundle, the OSGi specifications define different Java objects with which a management application can interact. Using this approach, a management agent can implement extensive management of the OSGi framework, as well as any service standardized. Mapping the Java interfaces to the specific remote management protocol and data model tree is up to the management agent. For runtime interaction with a bundle, a bundle can register a service in the service registry. However, this service interface is not standardized. Also, mapping the service interface to a general management model is not standardized. A current approach is to implement a proprietary service interface on all bundles to be managed. By tailoring this interface so that it easily maps to the management protocol primitives, it is simple for the management agent to map remote management commands to the bundle s service interface. The disadvantage is the proprietary service interface, so that 3rd party bundles might not be compliant. As a conclusion we can say that this current approach allows for extensive remote management of any aspect of the OSGi platform, but lacks a standardized service interface definition for bundles to implement. 4.2 Mobile specification approach The Mobile Expert Group has provided its own solution based on the OMA [3] Device Management [4] specification to provide a remote management solution. The OSGi Mobile specification contains two chapters related to remote management: chapter 3: detailing the mobile management tree chapter 117: detailing: the DMT Admin service, bundle plugin interface specification, the notification service Copyright NTT Corporation 2010

289 RFC-140 Residential Management Tree Page 9 of 48 Draft 24 November 2010 The Device Management Tree model of OMA-DM was chosen as meta-data model and operational model. However, it was intended to be mappable to other protocols. An analysis of mapping the Mobile specification DMT model to TR-069, however, shows that the current DMT model approach (as defined in the OSGi R4 Mobile Specification) introduces some issues. For example: Limitations for active or passive notifications on any parameter in the object tree A limited number of services have been mapped to the DMT model The complexity of mapping a new protocol to the OMA-inspired DMT model, which could imply performance issues on limited devices Support for TR-069 notifications TR-069 offers the feature of active and passive notifications. By setting a parameter s notification attribute, a remote manager requests to be notified with the parameter s new value at the time the value changes (active notification) or at the next periodic inform (passive notification). Notification can be configured on any parameter of the TR-069 object tree. This approach enables the remote manager to be informed not only of changes in status variables of the platform, but also of configuration changes performed by a local manager, e.g. through a local Web interface. The Mobile specification offers a few features that could help to implement TR-069 notification support: The DMT Admin service sends events using the Event Admin service when operations have been performed on nodes (nodes added, removed or copied; node values changed etc.) The OSGi Notification service defines a way to alert a remote management server. Protocol adapters on their turn have to implement a RemoteAlertSender interface (and register it) for use by the notification service. Notifications are sent by calling sendnotification on the notification service: The Monitor Admin service: A bundle can register a Monitorable service, to be used by the Monitor Admin service. By registering a Monitorable service, the bundle exposes access to a number of status variables. Notification can be implemented by the StatusVariable provider. If it does, it will call the update method on the Monitor Listener. The Monitor Admin service then generates an event on the Event Admin service. The Monitor service is currently also represented in the DMT tree. Two problems arise when trying to map the current approach to TR-069: TR-069 defines that notification is applicable to any parameter in the object tree. Currently, the DMT Admin service only send events for operations on DMT nodes that were performed using the DMT Admin API. For example: if configuration changes are performed by using the Configuration Admin service API, no events will be sent. Most of the current implementations do not perform all changes via the DMT Admin service. Therefore, the events sent by the DMT Admin service are an only subset and thus not very reliable as single source of events (and thus as single source of TR-069 notifications). The OSGi Monitor service only supports notification of changes on Status Variables, exposed through a Monitorable service, and enabled by the bundle to support on-change notification (i.e. dynamic Status Variables). Copyright NTT Corporation 2010

290 RFC-140 Residential Management Tree Page 10 of 48 Draft 24 November 2010 Requesting notification is not fully under the control of the remote manager. In the case of a bundle using the notification service, there is no standardized way to configure the bundle to send alerts when the value of one of the implemented DMT nodes changes. In the case of the monitor service, the sending of events can be controlled, but is limited to dynamic Status Variables. The current DMT Admin service has no attributes properties on its nodes to be used to configure notification behavior, such as active notification and passive notification defined in TR-069. Therefore, a remote manager cannot control the notification behavior of DMT nodes in a standardized way. To conclude, the current options, as provided in the Mobile specification, limit notification of parameter changes to StatusVariables, explicitly enabled for monitoring. There is no standardized approach available to monitor changes on any node in the DMT Limitations in the number of services available in the DMT The OSGi R4 Mobile specification mapped a number of services to the DMT tree. However, these services are limited to the services listed in the Mobile Specification. Other interesting services, as listed in the OSGi R4 Service Compendium are not yet mapped (standardized) in the DMT tree: The DMT tree defined in the Mobile Specification contains objects for the following services: Configuration Admin service Log service Monitor Admin service Application Admin service Conditional Permission Admin service Deployment service A number of areas that could be of interest to a remote manager are currently missing in the DMT tree: Startlevel management Bundle management: managing individual bundles as opposed to deployment packages (inventory, lifecycle management, exported services, ) Service management: getting a remote view on services registered in the service registry Permission Admin management Home Gateway Core Function management: handling Home Gateway core functions, such as firewall configuration and port forwarding control, from bundles running on an OSGi framework Mapping TR-069 to the OMA-DM inspired DMT model Within the OSGi Mobile specification, the choice has been made to model the DMT after OMA-DM. Copyright NTT Corporation 2010

291 RFC-140 Residential Management Tree Page 11 of 48 Draft 24 November 2010 As a result, creating an OMA-DM protocol adapter is quite straightforward. Although no major hurdles have been identified in creating a TR-069 protocol adapter, it is less straightforward: The TR-069 RPC primitives have to be translated to the DMT Admin service interface methods (which are OMA-DM RPC inspired). The TR-069 tree has to be mapped to the DMT tree. Translating object model specific features like DMT meta nodes, or TR-069 attributes is not straightforward. It might require specific extensions to the DMT, e.g. to support TR-069 attributes, or a single node in the DMT might result in multiple objects in a TR-069 data model, etc. The TR-069 data types have to be mapped to the DMT Admin data types. However, TR-069 data types, such as unsignedint and datetime (ISO 8601), cannot be translated appropriately into DMT Admin data types defined in the current specification. Translating these data types might result a limitation of the available value range and a complex object that consists of multiple nodes, respectively. 4.3 Conclusion The OSGi Mobile specification delivers a standardized data model (the DMT), and standardized interface (on the DMT Admin service) to enable remote management through a protocol adapter. However, the current specification lacks management objects for a number of interesting areas. Also, there is some support lacking for TR-069 notifications. Furthermore, since the DMT model is OMA-DM inspired, implementing a TR-069 protocol adapter is not straightforward, although not impossible. 5 Requirements REQUIREMENT[1]: A management tree, which is mappable to multiple remote management protocols, MUST be standardized. The solution MUST be mappable at least to OMA DM and TR-069 protocols. The model MUST be open to add new protocols in the future, like a possible common solution to substitute OMA-DM and TR-069. REQUIREMENT[2]: A bundle MAY implement a non-standard sub-tree of the management tree. The solution MUST support the management of this type of sub-trees. As such, it MUST define the interface to be implemented by the bundle to support this management. REQUIREMENT[3]: The management tree SHOULD cover bundle life cycle management and service monitoring. REQUIREMENT[4]: The management tree SHOULD cover all services defined in the release 4 of the OSGi specifications. If prioritization is needed, at least the following services MUST be covered: Start Level, Permission Admin, Conditional Permission Admin, Configuration Admin, Pacakge Admin and Log Service. REQUIREMENT[5]: Support for notification of parameter value changes is required for both framework and services sub-trees, as well as for bundles implementing a sub-tree of the management tree. Some lightweight mechanism MUST allow identifying which parameters have changed and have not already been notified. [REMARK]: Though the services which are Configuration Admin and Permission Admin, Conditional Permission Copyright NTT Corporation 2010

292 RFC-140 Residential Management Tree Page 12 of 48 Draft 24 November 2010 Admin are required as the following services in RFP87, they are removed from this requirement because they are not supported in this RFC. REQUIREMENT[7]: The solution MUST have a good performance in order to run on devices with limited resources. REQUIREMENT[8]: The solution SHOULD specify a guideline of RPC mapping between the DMT Admin service interfaces and remote management protocols, such as TR-069. REQUIREMENT[10]: The solution SHOULD enable bundles running on an OSGi framework to manage Internet Gateway functions of a Home Gateway by using an integrated management tree. REQUIREMENT[11]: The solution SHOULD enable bundles to hook into Internet Gateway functions such as DHCP. 6 Technical Solution This RFC defines the Residential Management Tree which is handled via DMT Admin service as it is available on an OSGi Residential Platform. The protocol used between the remote server and the device is not specified, but it is expected that the TR-069 protocol will be the management protocol used to manipulate this tree. Although the top level nodes of this tree depend on the user policy, this RFC supposes that TR-106 structural requirements defined by the Broadband Forum [6] will be adopted by the Residential Management Tree architecture. The top level nodes of a tree adhering to TR-106 are depicted in Figure 1 (See TR-106 Amendment1 [7]). The partial tree, enclosed by the dashed line, is specified by TR-106, which is expected to be used with the Residential Management Tree in many circumstances in residential service domain. This RFC does not define any restrictions on the architecture enclosed in the dashed line, and the ancestor nodes of /Device/Services/OSGi node can be arbitrarily defined by users. Therefore, the parent node of the OSGi node is referred to as $ in the following sections. The OSGi Residential Management Tree is a relative tree. Devices canplace the root of this tree anywhere in the Device Management Tree. In this RFC, this relative location in the Device ManagementTree is indicated with the $ sign. The root of the OSGi tree is set in the System property that must not change during runtime: residentialmanagement.osgi.root When residentialmanagement.osgi.root placed in./device/services/customnode/customnode2, The TR-069 path Device.Services.OSGi.1.Framework is mapped to./device/services/customnode/customnode2/osgi/1/framework. Copyright NTT Corporation 2010

293 RFC-140 Residential Management Tree Page 13 of 48 Draft 24 November 2010 The OSGi Residential Management Tree consists of a number of distinct parts as shown in Figure 1. Each of the sub-trees in the figure is explained in the following sections. Users of this tree may add a user-defined sub-tree under the $/OSGi/<instance_id> node. Moreover, there is no restriction on the use of sub-trees defined in Mobile Management Tree [8] as a user-defined sub-tree in the Residential Management Tree. $/OSGi/<instance_id> node is used to represent an instance of the OSGi framework on a device. In most cases there is only one instance of OSGi, so only $/OSGi/1 is available. However, in some cases such as multiple OSGi Frameworks run on the residential home gateway, there existseveral OSGi instances in the Residential Management Tree. In this case, the local OSGi framework on which the bundle registering Data Plugin of the Residential Management Tree is running should be identified, so that the DMT Admin implementation can access the indicated node path via appropriate way. Therefore, The leaf node, $/OSGi/<instance_id>/Local node, represents whether the OSGi Framework object is local or not as boolean value. How the Data Plugin of the Residential Management Tree on the local OSGi Framework finds and communicates with the other OSGi Frameworks is out of scope of this document. The pairs between each OSGi Framework and the corresponding <instance_id> must be kept persistently beyond restart of the local OSGi Framework and reconnection of other OSGi Frameworks. OSGiNumberOfEntries and BundleStateNumberOfEntries, ServiceStateNumberOfEntries, PackageStateNumberOfEntries are represent the number of those instances existing at the moment. When the instances are added or deleted, the value of the nodesmust be incremented or decremented, respectively. Fig.1 Overall Management Tree $/OSGi/<instance_id> node is used to represent an instance of the OSGi framework on a device. In most cases there is only one instance of OSGi, so only $/OSGi/1 is available. However, in some cases such as multiple OSGi Frameworks run on the residential home gateway, there existseveral OSGi instances in the Residential Management Tree. In this case, the local OSGi framework on which the bundle registering Data Plugin of the Residential Management Tree is running should be identified, so that the DMT Admin implementation can access the indicated node path via appropriate way. Therefore, The leaf node, $/OSGi/<instance_id>/Local node, represents whether the OSGi Framework object is local or not as boolean value. How the Data Plugin of the Copyright NTT Corporation 2010

294 RFC-140 Residential Management Tree Page 14 of 48 Draft 24 November 2010 Residential Management Tree on the local OSGi Framework finds and communicates with the other OSGi Frameworks is out of scope of this document. The pairs between each OSGi Framework and the corresponding <instance_id> must be kept persistently beyond restart of the local OSGi Framework and reconnection of other OSGi Frameworks. OSGiNumberOfEntries and BundleStateNumberOfEntries, ServiceStateNumberOfEntries, PackageStateNumberOfEntries are represent the number of those instances existing at the moment. When the instances are added or deleted, the value of the nodesmust be incremented or decremented, respectively. The Residential Management Tree adopts the complemental data model with the Mobile Management Tree defined in the OSGi Mobile Specification. On the one hand, Log which is one of top level node has definitions similar to the Mobile Specification. On the other, the Residential Management Tree has some original sub-trees: Framework, BundleState, PackageState, ServiceState,Filters, and BundleResouces. Especially, all of Framework, BundleState, PackageState, ServiceState Subtrees are designed to be compliant to TR-106 defined by Broadband Forum[7].. The Framework sub-tree is to manipulate the OSGi framework on which this management tree is implemented and to control the life cycle of installed bundles instead of the Deployment sub-tree defined in the Mobile Specification. The BundleState sub-tree is used to derive information of individual bundles. The PackageState and ServiceState sub-trees provide information of available Packages and Services on the OSGi framework, respectively. The Filters sub-tree is used to filter information contained in a tree. The BundleResouces sub-tree is used to derive resources in a bundle jar file. Basically, the structure of the sub-trees in the Residential Management Tree corresponds to the one defined in RFC-139 JMX Control of OSGi, which defines four interfaces for OSGi framework core APIs; FrameworkMBean, BundleStateMBean, PackageStateMBean and ServiceStateMBean. Although the fundamental architecture adheres to the API of RFC-139, some features such as command execution and structural data exchange are adjusted to realize functionality in a hierarchical object tree, because the Java interfaces are difficult to map completely to the Residential Management Tree which adheres to the DMT Admin model. One of the biggest differences is that returned values of OSGi Core API's methods cannot be returned in DMT Admin interfaces. The nodes for Overall Management Tree are explained in Table 6.1. Table 6.1 Nodes for Overall Management Tree URI Add Get Replace Delete Exec Type Cardinality Scope Description OSGi X node 1 P This node is root node of the Residential Management Tree. OSGiNumberOfEntries X unsig nedint 1 P A leaf node that represents the number of $/OSGi/<instance_id>nodes. OSGi/<instance_id> X node 0..* P This node is used to represent an instance of the OSGi framework on a device. OSGi/<instance_id>/ Local X bool 1 P A leaf node that represents whether the OSGi Framework object is local or not as boolean value. Copyright NTT Corporation 2010

295 RFC-140 Residential Management Tree Page 15 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description OSGi/<instance_id>/ BundleStateNumberOfEntries X unsig nedint 1 P A leaf node that represents the number of $/OSGi/<instance_id>/BundleState/<bundle_id > nodes. OSGi/<instance_id>/ ServiceStateNumberOfEntrie s X unsig nedint 1 P A leaf node that represents the number of $/OSGi/<instance_id>/ServiceState/<service_id > nodes. OSGi/<instance_id>/ PackageStateNumberOfEntri es X unsig nedint 1 P A leaf node that represents the number of $/OSGi/<instance_id>/PackageState/<id> nodes. 6.1 Legend All nodes of the Residential Management Tree are described in a table format. This table format defines the following meta information: Add An x indicates that the implementation must support the creation of the given node by the management system. Get An x indicates that the implementation must support retrieval of the properties of the given node (including the value). Replace - An x indicates that the implementation must support setting the value of the given node. Support for changing other properties is optional. Note, that this column does not correspond to the node attribute changing, which can be provided by an implementation even if the node value cannot be changed, for example in case it supports setting the Title property. Delete - An x indicates that the implementation must support deletion of the given node by the management system. Exec - An x indicates that the implementation must support the execute operation for the given node. Type - The node type for an interior node, or the data type for a leaf node. The following node and data types are defined: str, int, float, datemei, t, bin, xml, bool, b64.. Node type: node, list_node Data type: string, int, float, date, bin, bool, b64, long, unsignedint, nodeuri The list_node is the interior node must have node type of "org.osgi/1.0/listsubtree", which is defined in RFC141 as URI identifying an OMA DM Device Description Framework (DDF) file. The node type indicates that the sub-tree under this interior node contains list ; The name of child nodes must be a continuous numerical string from 1 and the values of the child nodes must be the element of the list. In addition, the Meta Node of child nodes must have the same format. Copyright NTT Corporation 2010

296 RFC-140 Residential Management Tree Page 16 of 48 Draft 24 November 2010 Cardinality - The range of occurrences of the given node. * means infinite. Scope - The scope indicates the creation strategy. It can have the following values: P - Permanent. A permanent node cannot be changed by the management system. It can, however, appear due to an internal device event, for example, the addition of a network interface. D - Dynamic. A node that must be created by the management system. Such a creation can then automatically create other nodes. A - Automatic. A node that is created automatically by a managed object if its parent node is created. NODE_TYPE An L indicates that the interior node must have node type of "org.osgi/1.0/listsubtree", which is defined in RFC141 as URI identifying an OMA DM Device Description Framework (DDF) file. The node type indicates that the sub-tree under this interior node contains list ; The name of child nodes must be a continuous numerical string from 1 and the values of the child nodes must be the element of the list. In addition, the Meta Node of child nodes must have the same format. 6.2 Framework Object Fig.2 Framework Object Copyright NTT Corporation 2010

297 RFC-140 Residential Management Tree Page 17 of 48 Draft 24 November 2010 The Framework Object is a managed object that allows manipulation of the OSGi framewor; StartLevel configuration, Bundle install, Framework Lifecycle control and Bundle lifecycle control. The Framework Object is an optional managed object, therefore this object does not have to be implemented if the user does not need to manipulate the framework. The tree structure of Framework Object can be accessed from the $/OSGi/<instance_id>/Framework sub-tree. Figure 2 shows the structure of the Framework Object sub-tree. The Framework Object consists of 5 parts; StartLevel, InstallBundle, FrameworkLifecycle, BundleControl and Ext. The Framework Object must support transactions because all changes to the $/OSGi/<instance_id>/Framework tree must be done in an atomic session to keep the OSGi Framework consistent. Only atomic sessions can perform the required changes to the node values. The following introduces the steps taken to install a bundle. At first, $/OSGi/<instance_id>/Framework/InstallBundle/<id> node must be created by ReadWriteDataSession#createInteriorNode() method, its children will be created automatically by the Framework Object. Next, the value of Location and URL must be set by ReadWriteDataSession#setNodeValue() method. After that, when TransactionalDataSession#commit() method is called, InstallBundle sub-tree should call BundleContext#installBundle(String, InputStream) method where the first argument is the Location and the second argument is the InputStream object retrieved from the specified URL. [REMARK] If commit() method is called BEFORE any value of Location and URL node is set by setnodevalue() method, InstallBundle sub-tree must NOT call installbundle() method. If commit() method is called AFTER either of them is set, installbundle() method must be called. Multiple bundles can be installed by just one commit() if multiple $/OSGi/<instance_id>/Framework/InstallBundle/<id> are created before one commit() is called. The BundleControl sub-tree provides bundle start level and life cycle operations of an individual bundle after installation. Regarding bundle life cycle control, the operation is basically conducted by indicating the desired state of the bundle; Active, Resolved or Uninstalled in the $/OSGi/<instance_id>/Framework/BundleControl/<bundle_id>/Lifecycle/DesiredState node. This sub-tree supports lazy activation and transient start (or stop). When commit() is called, Bundle#start(int option) or Bundle#stop(int option) is called where the argument is the value set in the $/OSGi/<instance_id>/Framework/BundleControl/<bundle_id>/Lifecycle/Option node. The value of Option node must be retained beyond the data plug-in bundle reboot. Details of the values are shown in Tale 6.1 [REMARK] A Protocol Adapter (or local manager) should set not only Resolved or Active in DesiredState but also Option node in same transactional session. The reason is that if a protocol adapter (or a local manager) sets only the DesiredState node, not the Option node, a value that the remote manager does not expect might be kept in the Option node. In that case, the operation resulting from this value is likely to differ from what the remote manager expects. Note that BundleUpdate is indicated directly as a command because this kind of operation does not represent the specific desired state of a bundle. The value set to BudnleUpdate node is the string of the new bundle's URL. The OperationResult node represents the result of the latest operation on this bundle. To use the TR-069 protocol to control the Residential Management Tree, the node name of $/OSGi/<instance_id>/Framework/InstallBundle/<id> should be represented by a numeric character string, not a literal node name such as Location or URL. The reason is that TR-069 has only the RPC called AddObject to create a new node in a tree, and the RPC can take as an argument the path name of the collection of objects for which new nodes are to be created. Copyright NTT Corporation 2010

298 RFC-140 Residential Management Tree Page 18 of 48 Draft 24 November 2010 [REMARK] According to TR-069, a dynamic node path in the Residential Management Tree should be defined as numeric character. Therefore, the path name of the new node should be assigned as an instance number by incrementing the number; the management system cannot specify the identifier of the new node. All nodes for the Framework Object sub-tree are explained in Table Table 6.12 Framework sub-tree Nodes URI Add Get Replace Delete Exec Type Cardinality Scope Description Framework X node 1 P Framework Root node. Framework/StartLevel X node 0,1 P Interior node that contains the values for StartLevel configuration. If the StartLevel service is unavailable, this node and its child nodes must not be created. Framework/StartLevel/ RequestedStartLevel Framework/StartLevel/ ActiveStartLevel Framework/StartLevel/ InitialBundleStartLevel Framework/FrameworkLifecy cle Framework/FrameworkLifecyc le/restart X X int 0,1 P A leaf node used to configure the Framework's StartLevel. When this node value is replaced or the Bundles sub-tree starts, StartLevel#setStartLevel with the specified value must be called. This value must be kept persistently. X int 0,1 P A leaf node that contains the Framework's current StartLevel. This node is read-only to get the Framework's StartLevel. X X int 0,1 P A leaf node used to configure the initial bundle StartLevel. When this node value is replaced or the Bundles sub-tree starts, StartLevel#setInitialStartLevel with the specified value must be called. X node 1 P Interior node that contains the values for Lifecycle control of the OSGi Framework. X X bool 1 P A leaf node used to restart the OSGi Framework. This node is writable to set the restart command. If this node value is replaced with 'TRUE', the Framework sub-tree must restart the OSGi Framework. When commit() is called, Framework Object MUST fire the DmtEvent before the framework restart operation by. MountPointEvenAdmint#sendEvent(). After the method returns,. Framework Object restarts the framework after the method returns. The topic of the even t MUST be set to info/dmtree/dmtevent/destructive_opera Copyright NTT Corporation 2010

299 RFC-140 Residential Management Tree Page 19 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description TION. Framework/FrameworkLifecy cle/shutdown Framework/FrameworkLifecyc le/update X X bool 1 P A leaf node used to shutdown the OSGi Framework. This node is writable to set the shutdown command. If this node value is replaced with 'TRUE', the Framework sub-tree must shutdown the OSGi Framework. When commit() is called, Framework Object MUST fire the DmtEvent before the framework shutdown operation by EvenAdmintMountPoint#sendEvent(). after it releases commit() method Framework Object shutdown the framework after the method returns. The topic of the event MUST be set to info/dmtree/dmtevent/destructive_opera TION. X X bool 1 P A leaf node used to update the OSGi Framework. This node is writable to set the update command. If this node value is replaced with 'TRUE', the Framework sub-tree must update the OSGi Framework. Framework Object MUST fire the DmtEvent before the framework update operation by EvenAdmint#sendEvent() after it releases commit() method. After the method returns,framework Object updates the framework after the method returns. The topic of the event MUST be set info/dmtree/dmtevent/destructive_opera TION. Framework/InstallBundle X node 1 P Interior node that contains the values for bundle installation. Framework/InstallBundle/<id> X X X node 0..* D Interior node that represents a bundle which will be installed to the OSGi Framework. This node is created for each bundle to be installed. When a transaction is committed, the Framework Object attempts to install the bundle specified under this node. See details of the installation operation described in the Location definition. This node must be stored persistently unless the Framework Object deletes it after installation succeeds. Framework/InstallBundle/<id>/ X X sstrin 1 A A leaf node used to set the bundle location under Copyright NTT Corporation 2010

300 RFC-140 Residential Management Tree Page 20 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description Location g which the specified bundle is installed. This node is writable because the node is used to install a bundle. If the Location is replaced by setnodevalue() method and the URL is empty String when commit() method is called, BundleContext#installBundle(location) must be called where location is the specified value in this node. When the transaction is committed where both this node Location and URL are replaced and commit() method is called, BundleContext#installBundle(location, in) must be called where location is the specified value of this node and in is an InputStream retrieved from the specified URL. InstallBundle sub-tree must call installbundle() method only if the value of Location node is set by setnodevalue() method and called commit() method. Optionally, the value of URL node can be set too. Even if commit() is called, installbundle() method must not be called if either of them is not set. If the installation of a bundle succeeds, the Framework Object must delete the Framework/InstallBundle/<id> node corresponding to the bundle and its descendants. If the installation of a bundle fails, the Framework Object will NOT retry the operation and instead creates an Error node to represent the reason for operation failure. Once the bundle install process fails, the <id> object is not checked when commit() method is called next time. If the Option is set to the value except default one, bundle start will be attempted after the installation. Framework/InstallBundle/<id>/ URL X X Sstrin g 1 A A leaf node used to be set the bundle's jar file URL from which the specified bundle is installed. This node is writable because the node is used to install a bundle. The default value of this node is an empty string. See details of the installation operation described in the Location definition. Framework/InstallBundle/<id>/ Option X X int 1 A A leaf node that can be usedto start the bundle immediately after its installation. When the node value is set to the value except default one,, the bundle will be started with the option specified in the node. The possible node values are: -1 : default value -- only install without start Copyright NTT Corporation 2010

301 RFC-140 Residential Management Tree Page 21 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description 0 : no start options are specified -- the bundle will be started without options. 1 : start transient -- the bundle will be started with START_TRANSIENT option. 2 : start with activation policy -- the bundle will be started with START_ACTIVATION_POLICY option. Both START_ACTIVATION_POLICY and START_TRANSIENT can be used simultaneously to start the bundle with activation policy and transiently (The node value is 3). Framework/InstallBundle/<id>/ Error X Sstrin g 0,1 A A leaf node used to represent the reason for an installation failure. When the installation of a bundle fails, the Framework Object should create this node and set a value specifying the error reason. Framework/BundleControl X node 1 P Interior node that contains the control functions for each bundle. Framework/BundleControl/ <bundle_id> Framework/BundleControl/ <bundle_id>/bundlestartleve l Framework/BundleControl/ <bundle_id>/lifecycle Framework/BundleControl// <bundle_id>/lifecycle/ DesiredState X node 0..* A Interior node that represents a Bundles instance. This node is automatically added and <bundle_id> is incremented. This number must equal the bundle id, which is Bundle#getBundleId() returns. X X int 1 A The configuration node for the StartLevel of the bundle. When the node value is gotten, this object must return the current StartLevel of the bundle. If this value is changed, StartLevel#setBundleStartLevel with the specified value must be called. X node 1 A This is a parent node for commands related to the bundle's life-cycle control. This sub-tree is described in detail later. X X int 1 A A leaf node used to control the bundle's lifecycle. When this node value is replaced with the state described below or the BundleControl subtree starts, the BundleControl sub-tree must change the bundle life-cycle to the specified bundle state. The BundleControl sub-tree must return an error, if the specified state cannot be understood. This state must be one of the following: 0 Uninstalled Copyright NTT Corporation 2010

302 RFC-140 Residential Management Tree Page 22 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description 4 Resolved 32 Active The Framework Object does not have to retry the operation if life-cycle control fails, but the error status should be written in the OperationResult. This value must be kept persistently. Framework/BundleControl/ <bundle_id>/lifecycle/bundle Update X X Sstrin g 1 A A leaf node used to update the bundle. This node is writable to set the update command. When this node value is replaced with an URL string, Bundle#update(InputStream) must be called where InputStream is the specified URL. If the specified URL is an empty string, Bundle#update() must be called so that the specified bundle is updated with the jar-file indicated by the BundleLocation. If the update fails, the Bundle object does not have to retry the operation. If DesiredState and Update are replaced during same transaction, BundleControl sub-tree must put update operation ahead of life cycle operation attributed by changing DesiredState Node value. Framework/BundleControl/ <bundle_id>/lifecycle/ Option X X int 1 A A leaf node used to set start or stop option. A Protocol Adapter (PA) (or local manager) should set not only DesiredState but also this node in the same transactional session. After called commit() method, Lifecycle sub-tree must call Bundle#start(int option) or Bundle#stop(int option). The value of this node must be kept beyond the data plug-in bundle reboot. Option node contains integer format data as below. 0:default 1:START_TRANSIENT or STOP_TRANSIENT 2:START_ACTIVATION_POLICY 3:START_ACTIVATION_POLICY START_TRANSIENT (Example 1) If a Protocol Adapter wants to start a Bundle transiently, the Protocol Adapter should set Active to DesiredState node and 1 to Option node. (Example 2)If a Protocol Adapter wants to start a bundle not transiently, the Protocol Adapter should set DesiredState node to Active and Option node to 0. Copyright NTT Corporation 2010

303 RFC-140 Residential Management Tree Page 23 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description (Example 3)If a Protocol adapter wants to stop a bundle transiently, it should set DesiredState node to Resolved and this node to 1. Framework/BundleControl/ <bundle_id>/lifecycle/ OperationResult X Sstrin g 1 A This node holds the latest operation's result which is conducted through the Framework/BundleControl/<bundle_id>/Lifecycle sub-tree, so that the Management System can derive the result of the bundle life-cycle operation. If the operation succeeds, the value string must be start with Success:. Otherwise it must start with Fail. Framework/BundleControlNu mberofentries X String unsig nedint 1 A A leaf node that represents the number of <bundle_id> nodes. Framework/Ext X node 1 P Interior node that can contain values for user extensions. 6.3 BundleState Object Copyright NTT Corporation 2010

304 RFC-140 Residential Management Tree Page 24 of 48 Draft 24 November 2010 Fig.3 BundleState sub-tree Figure 3 shows the BundleState sub-tree architecture. This sub-tree is used to obtain the information of a bundle from the OSGi framework. When a bundle is installed on the OSGi framework, a new node of $/OSGi/<instance_id>/BundleState/<bundle_id> is automatically added and <bundle_id> is incremented. In other words, <bundle_id> is equivalent to Bundle#getBundleId(). The identifiers including SymbolicName and Version are used to identify a bundle on the OSGi framework. BundleType, an integer value, represents the type of the bundle. Manifest represents the Manifest header by String value. StartLevel shows the bundle's start level on this OSGi framework. State shows the bundle state; Installed, Resolved, Starting, Active, Stopping and Uninstalled. Location, a String value, represents the BundleLocation of the bundle. Fragments, Hosts, Required, Requiring sub-trees contain the corresponding bundle identifiers. TrustedSignerCertificates and NonTrustedSignerCertificates sub-trees contain the Certificate chains. The one is only trusted certificates, the other is only NOT trusted certificates by the framework. All nodes for the BundleState Object sub-tree are explained in Table Table 6.23 BundleState sub-tree Nodes URI Add Get Replace Delete Exec Type Cardinality Scope Description BundleState X node 1 P This is a parent node for status information of the bundle. This sub-tree is detailed later. Copyright NTT Corporation 2010

305 RFC-140 Residential Management Tree Page 25 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description BundleState/<bundle_id> X node 0..* A A node that represents a Bundles instance. This number must equal the bundle id, which Bundle#getBundleId() returns. BundleState/<bundle_id>/ SymbolicName X Sstrin g 1 A The Bundle-SymbolicName of the bundle. BundleState/<bundle_id>/ Version X sstrin g 1 A The version of the bundle. BundleState/<bundle_id>/ BundleType X int 1 A A node indicating the type of the bundle. The node value must be equivalent to the value of PackageAdmin#getBundleType(). BundleState/<bundle_id>/ Manifest X sstrin g 1 A This node is a leaf node that contains Manifest headers as String. The node implementation must get Dictionary object by Bundle#getHeaders(). For converting the Dictionary object to String, this node must have the value adhering to the following format (LF means linefeed): <key>:<value>lf<key>:<value>lf... where order of appearance depends on its implementation. BundleState/<bundle_id>/ Status X node 1 A This node is the parent of the nodes that represent the status of the bundle. BundleState/<bundle_id>/ Status/Location X Sstrin g 1 A The BundleLocation of the bundle. BundleState/<bundle_id>/ Status/State BundleState/<bundle_id>/ Status/StartLevel BundleState/<bundle_id>/ Status/PersistentlyStarted X int 1 A The state of the bundle as returned by Bundle#getState(). This state is one of the following: 0 Not Available 2 Installed 4 Resolved 8 Starting 16 Stopping 32 Active X int 1 A The StartLevel of the bundle. Because this value is a read-only node in this sub-tree, user must use the Framework Object to configure the StartLevel. X bool 1 A The status of the bundle at the last shutdown of the OSGi Framework. If the bundle is Active when the OSGi Framework shutdowns, the value must Copyright NTT Corporation 2010

306 RFC-140 Residential Management Tree Page 26 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description be TRUE. Otherwise, the value must be FALSE. BundleState/<bundle_id>/ Status/LastModified X date 1 A The latest time at which the bundle has been modified. BundleState/<bundle_id>/Ho sts X list_n ode 1 A The sub-tree under this interior node contains the list of the bundles hosting this bundle; this node has the child nodes, each of which represents the bundle hosting this bundle. Even if there is no host bundle, this node must exist. BundleState/<bundle_id>/Ho sts/<n> X Sstrin g 0..* A A leaf node that represents the bundle ID of the host bundle. If there is no host bundle, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding bundle ID. BundleState/<bundle_id>/ Fragments X list_n ode 1 A The sub-tree under this interior node contains the list of fragment bundles; this node has the child nodes, each of which represents the fragment bundles. Even if there is no fragment bundle, this node must exist. BundleState/<bundle_id>/Fr agments/<n> X Sstrin g 0..* A A leaf node that represents the bundle ID of the fragment bundle. If there is no fragment bundle, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding bundle ID. BundleState/<bundle_id>/ Required X list_n ode 1 A The sub-tree under this interior node contains the list of the bundles requiring this bundle; this node has the child nodes, each of which represents the bundles requiring this bundle. Even if there is no required bundle, this node must exist. BundleState/<bundle_id>/Re quired/<n> X Sstrin g 0..* A A leaf node that represents the bundle ID of the required bundle. If there is no required bundle, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding bundle ID. BundleState/<bundle_id>/ Requiring X list_n ode 1 A The sub-tree under this interior node contains the list of the bundles required by this bundle; this node has the child nodes, each of which represents the bundles required by this bundle. Even if there is no requiring bundle, this node must exist. Copyright NTT Corporation 2010

307 RFC-140 Residential Management Tree Page 27 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description BundleState/<bundle_id>/Re quiring/<n> X Sstrin g 0..* A A leaf node that represents the bundle ID of the requiring bundle. If there is no requiring bundle, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding bundle ID. BundleState/<bundle_id>/ TrustedSignerCertificates BundleState/<bundle_id>/ TrustedSignerCertificates/<i d> X node 1 A Interior node that contains the trusted signer certificates of the bundle. Even if there is no signature, this node must exist. X node 0..* A A interior node that represents the X.509 Certificate chain. This node name must be a continuous numerical string from 1. BundleState/<bundle_id>/ TrustedSignerCertificates/<id >/CertificateChain X list_n ode 1 A The sub-tree under this interior node contains the list of the Distinguished Names in a trusted signers of the bundle; this node has the child nodes, each of which represents the Distinguished Names obtained from X509Certificate. BundleState/<bundle_id>/ TrustedSignerCertificates/<id >/CertificateChain/<n> X Sstrin g 0..* A A leaf node that represents the entries of the list of the Distinguished Names obtained from X.509Certificate, only trusted by the framework. Those can be gotten by Bundle#getSignerCertificates(SIGNERS_TRUSTE D). The last item is the root. The name must be a continuous numerical string from 1. BundleState/<bundle_id>/ NonTrustedSignerCertifica tes X list_n ode 1 A Interior node that contains the NOT trusted signer certificates of the bundle. Even if there is no signature, this node must exist. BundleState/<bundle_id>/ NonTrustedSignerCertificate s/<id> X node 0..* A A interior node that represents the X.509 Certificate chain. This node name must be a continuous numerical string from 1. BundleState/<bundle_id>/ NonTrustedSignerCertificate s/<id>/certificatechain X list_n ode 1 A The sub-tree under this interior node contains the list of the Distinguished Names in a NOT trusted signers of the bundle; this node has the child nodes, each of which represents the Distinguished Names obtained from X509Certificate. BundleState/<bundle_id>/ NonTrustedSignerCertificate s/<id>/certificatechain/<n> X sstrin g 0..* A A leaf node that represents the entries of the list of the Distinguished Names obtained from X.509Certificate, only NOT trusted by the framework. Those can be gotten by Copyright NTT Corporation 2010

308 RFC-140 Residential Management Tree Page 28 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description Bundle#getSignerCertificates(SIGNERS_ALL) except ones in TrustedSignerCertificates node. The last item is the root. The name must be a continuous numerical string from 1. BundleState/<bundle_id>/ BundleStateExt X node 1 A Interior node that can contain values for user extension. 6.4 PackageState Object The PackageState Object is a managed object that allows the package information to be derived. This object can be used to retrieve package dependencies between bundles. Copyright NTT Corporation 2010

309 RFC-140 Residential Management Tree Page 29 of 48 Draft 24 November 2010 Fig.4 PackageState Object Figure 4 shows the over all architecture of the PackageState object. The $/OSGi/<instance_id>/PackageState/<id> node is created for an individual package existing on the OSGi framework. This node represents a package's information including bundle dependencies. The pairs between each package and the corresponding <id> must be kept persistently as long as the package is exported from the same bundle, which means the same bundle ID, beyond restart of the OSGi Framework. The Name node contains a qualified package name, and the Version node contains the version number of the package. The ExportingBundle node shows a bundle identifier exporting the package. On the other hand, the ImportingBundles sub-tree shows the bundles importing the package. These nodes can be used to get information on packages shared between bundles. The PackageState Object may support only readable session because it does not contain any writable node. All nodes for the PackageState Object sub-tree are explained in Table Table 6.34 PackageState sub-tree Nodes Copyright NTT Corporation 2010

310 RFC-140 Residential Management Tree Page 30 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description PackageState X node 1 P PackageState Root node containing package information existing on the OSGi Framework. The children of this node must represent the actual package status when this sub-tree is accessed. PackageState/<id> X node 0..* A A node that represents the Package instance. This is equivalent to org.osgi.service.packageadmin.exportedpacka ge object. The name must be a continuous numerical string from 1. PackageState/<id>/ Name X Sstrin g 1 A The qualified name of the package. PackageState/<id>/Version X Sstrin g 1 A The version of the package. PackageState/<id>/ RemovalPending X bool 1 A A leaf node that represents the removal status of the package. If a bundle exporting the package has already been uninstalled or updated but the package is still used, this node must be TRUE. PackageState/<id>/ ExportingBundle X Sstrin g 1 A A leaf node that represents the bundle ID of the exporting bundle. The value is a bundle ID of string. PackageState/<id>/ ImportingBundles X list_n ode 1 A The sub-tree under this interior node contains the list of the ids of bundles importing the package; this node has the child nodes, each of which represents the ids of bundles importing the package. Even if there is no importing package, this node must exist. PackageState/<id>/ ImportingBundles/<n> X Sstrin g 0..* A A leaf node that represents the bundle ID of the importing bundle. If there is no importing bundle, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding bundle ID. Copyright NTT Corporation 2010

311 6.5 ServiceState Object RFC-140 Residential Management Tree Page 31 of 48 Draft 24 November 2010 The ServiceState Object is a managed object that allows the service information to be derived. This object can be used to retrieve service dependencies between bundles. Fig.5 ServiceState Object Figure 5 shows the over all architecture of the ServiceState object. The $/OSGi/<instance_id>/ServiceState/<service_id> node is created for an individual service instance existing on the OSGi framework. This node represents a service's information including registering bundle and using bundles. Registering a service to the OSGi framework automatically adds a new Service instance under the $/OSGi/<instance_id>/ServiceState node with incrementation of <service_id>. In other words, <service_id> equals the service.id of the service instance in the OSGi framework. The Properties node contains service properties of the service, which include the interface names implemented by the service. The Properties node must contain all service properties which consist of string, boolean or numeric data types including single-dimension arrays or vectors. However non-serializable data types can be discarded from the Properties sub-tree, since these types of properties are difficult to be represented in object trees. See for the detail of it. The RegisteringBundle node shows the id of the registering bundle. On the other hand, the UsingBundles sub-tree shows bundles using the service. These nodes can be used to get information on the relationships between registering bundle and using bundles. In order to get service interface names of a service, you should first find the <id> to obtain the node $/OSGi/<instance_id>/ServiceState/<service_id>/Properties/<id>objectClass/KeyValues/<n> node wcan be used.hose value is objectclass. After that, the service interface name is obtained from $/OSGi/<instance_id>/ServiceState/<service_id>/Properties/<id>/Values/<n>. The ServiceState Object may support only readable session because it does not contain any writable node. Copyright NTT Corporation 2010

312 RFC-140 Residential Management Tree Page 32 of 48 All nodes for the ServiceState Object sub-tree are explained in Table Draft 24 November 2010 Table 6.45 ServiceState sub-tree Nodes URI Add Get Replace Delete Exec Type Cardinality Scope Description ServiceState X node 1 P ServiceState Root node containing package information existing on the OSGi Framework. The children of this node must represent the actual service status when this sub-tree is accessed. ServiceState/<service_id> X node 0..* A A node that represents the Service instance. This number must match the service id of the OSGi Framework. ServiceState/<service_id>/ Properties ServiceState/<service_id>/ Properties/<id> X node 1 A Holds the <id> nodes that contain the key and values for the service properties. X node 0..* A A interior node that represents the service property instance of this sub-tree. This node name must be numerical string from 1. The node holds the key and value of an entry in the service property Dictionary. The value is defined by its type, cardinality and value node. ServiceState/<service_id>/ Properties/<id>/Key X Sstrin g 1 A A leaf node that represents the key of the service property. ServiceState/<service_id>/ Properties/<id>/Types X Sstrin g 1 A List of types of the properties' values. See Service Property Dictionary nodes section. ServiceState/<service_id>/ Properties/<id>/Cardinality X Sstrin g 1 A Cardinality of the property. See Service Property Dictionary nodes section. The value is either: scalar, collection or array. ServiceState/<service_id>/ Properties/<id>/Values X list_n ode 1 A The sub-tree under this interior node contains the list of the actual values; this node has the child nodes, each of which represents the actual values. ServiceState/<service_id>/ Properties/<id>/Values/<n> X Sstrin g bin int long bool 1..* A A leaf node that contains a value which is defined by the Type node in this sub-tree. The name must be a continuous numerical string from 1. See Service Property Dictionary nodes section. Copyright NTT Corporation 2010

313 RFC-140 Residential Management Tree Page 33 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description float ServiceState/<service_id>/ PropertiesNumberOfEntries X String unsig nedint 1 A A leaf node that represents the number of <id> nodes. ServiceState/<service_id>/ RegisteringBundle X Sstrin g 1 A A leaf node that represents bundle ID of the registering bundle. The value is a bundle ID of string. ServiceState/<service_id>/ UsingBundles X list_n ode 1 A The sub-tree under this interior node contains the list of the ids of bundles using the service; this node has the child nodes, each of which represents the ids of bundles using the service. Even if there is no using bundle, this node must exist. ServiceState/<service_id>/ UsingBundles/<n> X Sstrin g 0..* A A leaf node that represents the bundle ID of the using bundle. If there is no using bundle, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding bundle ID Service Property Dictionary nodes The service property Dictionary consists of key-value pairs. The service property Dictionary is mapped to a subtree. The URI for a service property item is the following: $/OSGi/<instance_id>/ServiceState/<service_id>/Properties/<id> These sub-nodes are: Key Represents the key of the service property. Type Type contains only one Java type name of Values such as java.lang.float, float, java.lang.string, char, etc. Cardinality Defines if the value is a scalar, an array, or a vector. It can take the following values: scalar For simple, unstructured values, like a string or a byte[]. array When the value is a Java array (but not byte[]). collection When the value must be a Java Collection object. Copyright NTT Corporation 2010

314 RFC-140 Residential Management Tree Page 34 of 48 Draft 24 November 2010 Values If Cardinality is array, Values contains the list of values of the service properties. Otherwise if Cardinality is collection, Values contains the list of values of the service properties value, where all values have the same Java type. That is the limitation because it would be too complex to handle different Java types in Collection's values. Otherwise, Values contains only one value. The actual value (Values child nodes) is mapped to a DmtData type if possible. If this mapping is not possible, the node must be a string node and the Java class of the given type must be able to parse the value in a constructor. [Remarks] The mapping of data types between DMT Admin and TR-069 are described in RFC Filters Object The Filters Object is a managed object that searches the nodes in a tree that correspond to the filter expression. This Filter Object is a generic mechanism for the whole management tree below the $/OSGi node although Filters sub tree is located under the $/OSGi/<instance_id> node. In other words, the Filter Object plugin must be able to filter all nodes in the tree except Filters Object itself. The Filters Object can be used to group bundles, packages, services and other information in the tree. Since the filter string set in the Filter node has no restriction in terms of its usage policy, users can use this function in accordance with their needs. Fig.6 Filters Object The $/OSGi/<instance_id>/Filters object is used to search nodes by filtering values or names of nodes located under the sub-tree specified by $/OSGi/<instance_id>/Filters/<search_id>/Target. At first, the user needs to create the $/OSGi/<instance_id>/Filters/<search_id> node by incrementing the <search_id> number, which should be a numeric character string as demanded by the TR-069 protocol. Then the user sets the desired partial path in the $/OSGi/<instance_id>/Filters/<search_id>/Target node, that specifies the sub-tree required to provide information as the result, and sets an appropriate filter string in $/OSGi/<instance_id>/Filters/<search_id>/Filter. When $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList node is accecced, the Filter Object plugin must search all sub-trees that match the filter specified in $/OSGi/<instance_id>/Filters/<search_id>/Filter. The scope of this search is not any nodes in the sub-tree under Target but only any child interior nodes of the Target, which has the properties that matches the filter. Here, the child leaf nodes and the child interior nodes which represents list are considered as the properties of the interior node, while the child interior nodes which does not represents list are Copyright NTT Corporation 2010

315 RFC-140 Residential Management Tree Page 35 of 48 Draft 24 November 2010 not. Then, $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList node contains the list of the absolute paths of the matched child interior nodes from the $ node. When either of $/OSGi/<instance_id>/Filters/<search_id>/Result node is accessed, the search must be done and $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList node must be set as described above and then the copied subtree under the matched child interior nodes must be aligned under the $/OSGi/<instance_id>/Filters/<search_id>/Result node with the absolute path from the $ node. Remark that the copied Subtree must be the one not when the $/OSGi/<instance_id>/Filters/<search_id>/Target node or the $/OSGi/<instance_id>/Filters/<search_id>/Filter node is set, but when the $/OSGi/<instance_id>/Filters/<search_id>/Result node is accessed. $ can be represented the path which starts with./ as./device/services/.... Therefore the "./" can be used only in the beginning of the Uri according to DMT Uri rules, in such case, Filters object must remove the./ from the Result subtrees. For example, when the./device/services/ is given as $ node path, the result subtree must be represented.../filters/<search_id>/result/device/services/osgi/.... The <search_id> node is a dynamic node which means that the path name of the new node should be assigned as an instance number by incrementing the largest existing number as demanded by TR-069. Therefore, the node name should be defined as numeric character in the Residential Management Tree. All nodes for the Filters Object sub-tree are explained in Table 6.5. Table 6.5 Filters Object sub-tree Nodes URI Add Get Replace Delete Exec Type Cardinality Scope Description Filters X node 1 P The root node of Filters Object. Filters/<search_id> X X X node 0..* D Represents a filter search request. This node is created to set the filter expression and to get the sub-trees, which match with the filter expression. The <search_id> is assigned in ascending order to Filters instances when they are set. This is a unique ID of Filters instance and must be kept persistently. Filters/<search_id>/ Target X X Sstrin g 1 A Partial path to the sub-tree under which Filter is going to be matched. This must be the absolute path of the top node name of the sub-tree. The default value of this node is an empty string, which means no filtering must be done. This value must be kept persistently. Filters/<search_id>/Filter X X string 1 A Contains the filtering expression. The filter must be given in the OSGi Filter format. See Filter and target Expression section. An empty string indicates that no filtering must be done. An empty string is the default value for this node. This value must be kept persistently. Copyright NTT Corporation 2010

316 RFC-140 Residential Management Tree Page 36 of 48 Draft 24 November 2010 URI Add Get Replace Delete Exec Type Cardinality Scope Description Filters/<search_id>/Result X node 1 A Matched sub-trees are stored under the Result node. Any children of this node must be contained as as a snapshot, represent the actual status of the sub-tree whenever the descendant nodes in this sub-tree are accessed.it will be created only when Result sub-tree or ResultUriList is accessed at the first time and never changed. The result must be only those sub-trees that satisfy the specified Filter node. And the filtered sub-trees must include all nodes located under the sub-tree specified by the Target node. See Filter and Target Expression section. Filters/<search_id>/ResultUri List X list_n ode 1 A The sub-tree under this interior node contains the list of the matched node URIs; this node has the child nodes, each of which represents the matched node URIs. Even if there is no matched URI, this node must exist. Filters/<search_id>/ResultUriP athlist/<n> X String node uri 1 A A leaf node that represents the matched interior node path which is contained as as a snapshot. The snapshot will be created only when Result sub-tree or ResultUriList is accessed at the first time. If there is no matched path, this node must not exist. The name must be a continuous numerical string from 1. The value is corresponding node path. See Filter and Target Expression section Filter and Target Expression The expression of $/OSGi/<instance_id>/Filters/<search_id>/Target must be a partial path from the $ node to the top node of the target sub-tree to be filtered and must end with /, which implies that a partial path must indicate an interior node. The characters * and - must be allowed to be used in the path as a wild-card; * indicates a wild-carded node for 1 level, while - indicates multiple levels in a node path respectively. Multiple wild-card can be used in a node path. If an inappropriate string, such as a string including an incorrect format path, is specified in $/OSGi/<instance_id>/Filters/<search_id>/Target, the Filters Object should throw a DmtException to the caller and should keep the Target node value as an empty string. In case that the path which does notn't exist in the current subtrees is specified in $/OSGi/<instance_id>/Filters/<search_id>/Target, the Result subtree must have not havingave be leno children. The filter expression of $/OSGi/<instance_id>/Filters/<search_id>/Filter should be a LDAP search filter (RFC See Filter for a description of the filter string syntax.). This expression is equivalent to the OSGi Filter format. Copyright NTT Corporation 2010

317 RFC-140 Residential Management Tree Page 37 of 48 Draft 24 November 2010 The key string in a filter must be any of the names of the node whose parent node is the interior child nodes of the node specified by $/OSGi/<instance_id>/Filters/<search_id>/Target. Therefore it must not contain /. If the indicated node does not exist, the Filters Object must not create sub-trees under the Result node and ResultUriList node. A wild-card must not be allowed to be used in a key string. Both interior node which has leaf child nodes as list and leaf node can be specified as the key string of a filter. If an interior node which has the node type of "org.osgi/1.0/listsubtree" is specified as the key string, node values of child nodes of the specified interior node must be recognized as the target values to be matched. Other interior node is out of scope of searches. On the other hand, if a leaf node is specified, the value of the specified leaf node must be recognized as the target value. A wild-card can be used at the end of the value string to conduct prefix-searches in either cases. In a filter expression, types of value should be ignored because the Filter Object must recognize the filter strings as String. Therefore, the filter matching operation demands that the filter value should be translated into the type appropriate for each leaf node. Filters object must contain the result of search as a snapshot in $/OSGi/<instance_id>/Filters/<search_id>/Result sub-tree and $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList. It means that Result sub-tree and ResultUriList node do notn't always have actual status of the sub-tree. The snapshot will be created when $/OSGi/<instance_id>/Filters/<search_id>/Result sub-tree or $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList. is accessed at the first time. The snapshot has the time out value which is set in system property. The unit of it is second. The default value depends on the implementation. The Filters object must remove the <serch_id> object when the snapshot times out. The snapshot will be removed when deletenode() method is called for".../filters/<search_id>". In addition, Framework or FiltersDataPlugin is restarted, all of <search_id> object should not be persistent beyond the restrart of Framerok or DataPlugin of Filters Objectwill be removed. When the $/OSGi/<instance_id>/Filters/<search_id>/Result sub-tree or the $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList is accessed, the returned values must reflect the current situation; the detailed mechanism of the synchronization depends on the implementation. The Filters Object searches nodes that satisfy the specified keys and values in $/OSGi/<instance_id>/Filters/<search_id>/Filter among the child nodes of the node specified by $/OSGi/<instance_id>/Filters/<search_id>/Target, and must create the $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList and the $/OSGi/<instance_id>/Filters/<search_id>/Result node. The absolute node path from the $ node must be created with the actual node name of the wild-card appearing in the node path specified by $/OSGi/<instance_id>/Filters/<search_id>/Target. The sub-trees under the $/OSGi/<instance_id>/Filters/<search_id>/Result and the $/OSGi/<instance_id>/Filters/<search_id>/ResultUriList must be read-only in order to keep consistency among data-plugins related to the filter search. The Filter Object must prevent attempts to access the sub-tree to change node value or properties, and must throw DmtException to the caller. Copyright NTT Corporation 2010

318 RFC-140 Residential Management Tree Page 38 of 48 Draft 24 November 2010 The following expressions are examples of the Filter and Target: [Case1] Simple Target and Filter usage Target: $/OSGi/1/BundleState/ Filter: (SymbolicName=org.osgi.*) Bundles whose Bundle-SymbolicName correspond to org.osgi.* are matched. The Result node contains corresponding sub-trees that have absolute node paths descending from $ node. A possible sub-tree under the Result node is described below ($ node should be changed to the actual node path depending on each execution environment): Copyright NTT Corporation 2010

319 RFC-140 Residential Management Tree Page 39 of 48 Draft 24 November 2010 [Case2] Filter including an interior node name as a key value and Target including * as a wild-card Target: $/OSGi/*/PackageState/ Filter: (&(ExportingBundle=5)(ImportingBundles=10)) Packages that have a ExportingBundle node contained 5 as a value and have a leaf node contained 10 among children nodes of ImportingBundles are matched. The filter search is performed for all OSGi Frameworks included in the management tree, because the <instance_id> of the OSGi Framework is represented as a wildcard. The Result node contains corresponding sub-trees that have absolute node paths descending from $ node. A possible sub-tree under the Result node is Copyright NTT Corporation 2010

320 RFC-140 Residential Management Tree Page 40 of 48 Draft 24 November 2010 described below ($ node should be changed to the actual node path depending on each execution environment): [Case3] Filter for service properties filtering Target: $/OSGi/1/ServiceState/*/Properties/ Filter: (&(Key=application)(Values=automation)) Services that have properties including application as a key and automation as a value are matched. The Result node contains corresponding sub-trees that have relative node paths descending from the <service_id> node. A possible sub-tree Copyright NTT Corporation 2010

321 RFC-140 Residential Management Tree Page 41 of 48 Draft 24 November 2010 under the Result node is described below ($ node should be changed to the actual node path depending on each execution environment): [Case4] TargetSubtree including - as multiple level wild-card TargetSubtree: $/OSGi/-/BundleControl/ Filter: (BundleStartLevel=2) Bundles whose BundleStartLevel correspond to 2, which is obtained by calling StartLevel#getBundleStartLevel(Bundle), are matched. The filter search is performed for all Copyright NTT Corporation 2010

322 RFC-140 Residential Management Tree Page 42 of 48 Draft 24 November 2010 OSGi Frameworks included in the management tree, because the <instance_id> of the OSGi Framework is included in the wild-card. The Result node contains corresponding sub-trees that have absolute node paths descending from $ node. A possible sub-tree under the Result node is described below ($ node should be changed to the actual node path depending on each execution environment): Copyright NTT Corporation 2010

323 6.7 BundleResources Object RFC-140 Residential Management Tree Page 43 of 48 Draft 24 November 2010 Fig.7 BundleResources sub-tree The BundleResources sub-tree is optional and it is used to derive resources in the bundle jar file. The BundleResources sub-tree consists of interior and leaf nodes that correspond to actual file-paths and files in the jar file respectively, so that a remote manager can derive a bundle's resources by a simple operation. For example, suppose there is /META-INF/Manifest.mf file in a jar file, The Bundle Resources sub-tree will specify the file with: $OSGi/<instance_id>/BundleResources/<bundle_id>/<filedir_id>/FileName = META-INF $OSGi/<instance_id>/BundleResources/<bundle_id>/<filedir_id>/<file_id>/FileName = MANIFEST.MF $OSGi/<instance_id>/BundleResources/<bundle_id>/<filedir_id>/<file_id>/Content = the content of the MANIFEST.MF file The <file_id > node is automatically created and represents a directory or file included in a jar file. The Content leaf node exists only for files and is missing for the directories. The <bundle_id> node must indicate the root directory of the jar file. The name of <file_id> should be put a mangled file name which is obtained by Uri#mangle(String). The reason why the file or directory name is not used as the node name is that the node name length might have its max size in Dmt Admin specification. See,getMaxSegmentNameLength() method of info.dmtree.uri. Then The file or directory name is placed in the leaf node <file_id>/filename. On the other hand, <file_id>/content node is also created automatically as a leaf node and represents the content of the file in a jar file. The content is encoded in base64 format. If the size of the content exceeds a limit which depends on the BundleResources Object implementation, the BundleResources Object should abort the reading of file content and should throw a DmtException. Because the BundleResources sub-tree is created automatically based on the actual file architecture of the indicated jar file, this sub-tree must be read-only. A remote manager can not add, replace, delete and exec nodes in this sub-tree. Copyright NTT Corporation 2010

324 RFC-140 Residential Management Tree Page 44 of 48 Draft 24 November 2010 Note: Assume that adopted remote management protocol implements a method that retrieves data of all nodes under the specified node recursively (such as GetParameterValues RPC of TR-069 protocol). When a remote manager indicates $/OSGi/<instance_id>/BundleResources/<bundle_id> node or ancestor nodes of it, heavy data transaction between the remote manager and client would occur because the BundleResources sub-tree contains all file of the bundle jar-file. Therefore, when using such kind of method in an operation, a remote manager should carefully specify the node in terms of performance. [REMARK] A considered alternative of the BundleResources sub-tree architecture is shown in section 7. All nodes for the Resources Object sub-tree are explained in Table 6.6. Table 6.6 Resources sub-tree Nodes URI Add Get Replace Delete Exec Type Cardinality Scope Description BundleResources X node 1 P This is a parent node for resources included in the bundle. This sub-tree is detailed later. BundleResources/<bundle_id > BundleResources/<bundle_id> /<file_id> X node 0..* A A node that represents a Bundles instance. This number must equal the bundle id, which Bundle#getBundleId() returns. X node 0..* A Represents the jar entry identifier of a file or a directory. This node is automatically created to include children with details about file or directory. The name of <file_id> should be put a mangled file name which is obtained by Uri#mangle(String). BundleResources/<bundle_id> /<file_id>filename Sstrin g 1 A Represents the file or directory name. BundleResources/<bundle_id> /<file_id>/content X b64 0,1 A The content of the file specified in the FileName node. This leaf node is automatically created for an individual file in a bundle jar-file. The node value is encoded in base 64 format. The node exists only for files and is missing for directories. Copyright NTT Corporation 2010

325 6.8 Limitations RFC-140 Residential Management Tree Page 45 of 48 Draft 24 November 2010 The Residential Management Tree has several limitations due to the specification of a remote management protocol (TR-069) utilized with the DMT Admin service. The following section describes these limitations. Maximum and Minimum values of numeric parameters Due to the TR-069 specification, only the data types Integer or Unsigned Integer are available in the Residential Management Tree. Therefore, the maximum value of an unsigned integer should be less than , and the minimum value should be greater than or equal to Consequently, the Bundle ID and the service.id which are originally a Long value in the OSGi specification should be represented as integer value in the Residential Management Tree Life-cycle control of the Framework The life-cycle control of the OSGi Framework depends on the implementation of the framework on which the Residential Management Tree can run. This RFC doesn't specify the results of calling $/OSGi/<instance_id>/Framework/FrameworkLifecycle/* Service Properties Expression The following list summarizes the restrictions and rules that should be obeyed in order to maintain a valid ServiceState Object. Complex data types, multiple-dimension arrays or vectors might be discarded from the Properties subtree, since these types of properties are difficult to be represented in the object tree if the data isn't serializable. 6.9 Future Work In TR-069 protocol way, Management Server (ACS) cannot provide enough information to the Configuration Object and Policy Object which are defined in the Mobile Management tree. Therefore we will investigate this task as a future work. Copyright NTT Corporation 2010

326 RFC-140 Residential Management Tree Page 46 of 48 Draft 24 November Considered Alternatives 7.1 BundleResources sub-tree architecture There is considerable alternative for designing the BundleResources sub-tree to retrieve resources inside the bundle jar file. The following architecture is another design of the BundleResources sub-tree, which was eventually discarded as the result of discussion. The <resource_id> node is a dynamic node, which means the path name of the new node is automatically assigned as an instance number by the Bundles Object. In advance, the management system needs to create the <resource_id> node. Then it has to indicate the file path by setting the Path node parameters and can retrieve the contents of the specified file as the value of the Content node. This architecture has pros and cons compared to the proposed architecture in Section 6.8. First, this architecture enables a scalable implementation because the remote manager is able to decide which resources should be retrieved from bundles arbitrarily. The remote manager, therefore, can avoid heavy data traffic between remote manager and client, when an ancestor node of the Resources sub-tee is specified by the GetParameterValues RPC defined in the TR-069. Secondly, the typical usage of the Resources sub-tree would be for diagnostics senarios; when some problems occur, a remote operator who needs to find the cause of the problem retrieves the content of the bundle JAR file by using this sub-tree. But this architecture limits the diagnostics ability of a remote manager. The remote manager has to check many files by repetitively creating <resources_id> nodes until the cause of problem is detected. This situation prevents an effective diagnostics through the Resources sub-tree. On the other hand, the proposed architecture in Section 6.8 provides a better diagnostics ability than this but the performance decreases in terms of data transactions when retrieving data recursively. Copyright NTT Corporation 2010

327 RFC-140 Residential Management Tree Page 47 of 48 Draft 24 November 2010 Consequently, the architecture proposed in Section 6.8 is chosen for the Resources sub-tree due to the effectiveness of the diagnostics ability, even though there is a risk of a performance drawback when a remote manager indicates $/OSGi/<instance_id>/BundleResources/<bundle_id> node or ancestor nodes. 8 Security Considerations All security requirements follow the DMT Admin specification. 9 Document Support 9.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. OMA, Open Mobile Alliance. The mission of the Open Mobile Alliance is to facilitate global user adoption of mobile data services by specifying market driven mobile service enablers that ensure service interoperability across devices, geographies, service providers, operators, and networks, while allowing businesses to compete through innovation and differentiation. [4]. OMA Device Management specification v1.2. The goal of the Device Management Working Group is to specify protocols and mechanisms that achieve management of mobile devices including the necessary configuration to access services and management of the software on mobile devices. [5]. CPE WAN Management Protocol, TR-069 amendment 2, December [6]. The Broadband Forum is a global consortium of nearly 200 leading industry players covering telecommunications, equipment, computing, networking and service provider companies. Established in 1994, originally as the ADSL Forum and later the DSL Forum, the Broadband Forum continues its drive for a global mass market for broadband, to deliver the benefits of this technology to end users around the world over existing copper telephone wire infrastructures. [7]. Data model template for TR-069 enabled devices, TR-106 amendment 1, November 2006 Copyright NTT Corporation 2010

328 RFC-140 Residential Management Tree Page 48 of 48 Draft 24 November 2010 [8]. OSGi Service Platform Mobile Specification, Release 4 Version 4.0, July 2006 [9]. RFC Author's Address Name Company Address Koya Mori NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice [email protected] Name Company Address Ikuo Yamasaki NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice [email protected] Name Company Address Shigekuni Kondo NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice [email protected] 9.3 Acronyms and Abbreviations 9.4 End of Document Copyright NTT Corporation 2010

329 RFC-141 DMT Admin Extension Page 1 of 55 Draft 19 November 2010 RFC-141 DMT Admin Extension Public Draft 55 Pages Abstract Different industries are interested in applying OSGi to advance their businesses, in which remote management is a key issue. In the residential area, the TR-069 is the one of the de-facto standard protocol for remote management. The best way to realize remote management based on the TR-069 on OSGi is utilizing DMT Admin service, which has been defined in the OSGi Alliance for the mobile device management. In this case, TR-069 is implemented as a protocol adapter of the DMT Admin. The DMT Admin service, however, is designed mainly for OMA-DM, which is the de-facto standard protocol in mobile area. Although these protocols have the similar objectives and functionality, there are several differences. One of which is the data types definition. Therefore, this RFC defines new data types in the DMT Admin service. Copyright NTT Corporation 2010

330 1 Document Information RFC-141 DMT Admin Extension Page 2 of 55 Draft 19 November Table of Contents 1 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Problem Description Management agent making use of OSGi standardized Java interfaces Mobile specification approach Support for TR-069 notifications Limitations in the number of services available in the DMT Mapping TR-069 to the OMA-DM inspired DMT model Management of overlapping trees Management of lists Limitations in Event handling Conclusion Requirements Technical Solution Additional data types Additional system properties Scaffold nodes Meta data of scaffold nodes Node type of scaffold nodes Examples Scaffold nodes and Events Mount points Definitions How to specify mount points? Required checks during plugin mapping API Extensions Mapping Examples Support for lists List Subtree Node Enumerated Plugins (Tables) Examples for enumerations of plugins Copyright NTT Corporation 2010

331 RFC-141 DMT Admin Extension Page 3 of 55 Draft 19 November Extension for event handling Eventing for internal changes in a plugins subtree Eventing for internal changes of list subtrees Eventing sequence for atomic sessions Destructive Operations The MountPlugin and MountPoint Interfaces The MountPlugin interface The MountPoint interface Javadoc Definition of constants for literals Additional Data Types Mount Plugin API MOUNT_POINTS DmtException.METADATA_MISMATCH DmtException.COMMAND_NOT_ALLOWED info.dmtree.dmtevent Interface info.dmtree.synchronousdmteventlistener Considered Alternatives Security Considerations Document Support References Author's Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in 9.1. Source code is shown in this typeface. 1.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial Sep Initial Draft Koya Mori, NTT Corporation, [email protected] Copyright NTT Corporation 2010

332 RFC-141 DMT Admin Extension Page 4 of 55 Revision Date Comments 2nd Jan nd Draft Oct Public Draft Draft 19 November 2010 Generic setter/getter methods are added. Limitation of notification is described April For 3 rd Public Draft Koya Mori, NTT Corporation, [email protected] Javadoc and Considered Alternatives are added. Notification property definition is changed. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Shigekuni Kondo, NTT Corporation, [email protected] Based on the discussion of REG F2F in Mountain View, the following modifications are done; abstract was modified. Requirements which this RFC cannot meet are removed in Section 5. all descriptions on notifications are removed in Section 6. Section 7.1 is added for future work on notification. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Based on discussions from REG F2F & Bundlefest in Girona : overlapping of plugins support for lists description of mount points required api extensions Steffen Druesedow, Deutsche Telekom AG re-structured chapter 6 added lots of figures and step-by-step examples integrated decisions from a number of Bugzilla discussions added placeholders for results of pending discussions Steffen Druesedow, DTAG, [email protected] Copyright NTT Corporation 2010

333 RFC-141 DMT Admin Extension Page 5 of 55 Revision Date Comments Draft 19 November Updates according to comments from Ikuo and Evgeni Steffen Druesedow, DTAG, [email protected] Updates according to comments from Ikuo and Evgeni. Additionally: some changes to MountPlugin section (incl. API) changed start-index of plugins lists to 1 Steffen Druesedow, DTAG, [email protected] Added chapters for format and meta data of scaffold nodes described retrieval of meta data for list subtree nodes added definition of several string literals to the Javadoc section added properties-parameter to the MountPoint.postEvent() methods added some postevent related stuff to security section (still misses other eventing related updates) Steffen Druesedow, DTAG, [email protected] Filled chapter for eventing extensions for subtree lists with latest decisions summarized discussions about eventing sequence in atomic sessions changed FORMAT_REFERENCE to FORMAT_NODE_URI, including corresponding API's added more constants for string laterals to API section Steffen Druesedow, DTAG, [email protected] Fixed a lot of inconsistencies in the Javadocs added description of URI and SEGMENT related system properties Steffen Druesedow, DTAG, [email protected] Copyright NTT Corporation 2010

334 RFC-141 DMT Admin Extension Page 6 of 55 Revision Date Comments Draft 19 November Added statement about immutability of system properties for the URI format during VM lifetime. changed description of scaffold metadata to table format added remark about required specification improvents for Eventing in atomic sessions enhanced description of MountPoint Eventing including required DmtEvent API changes fixed a number of formatting issues added description of destructive operation event rewrote chapter about eventing of internal changes of list subtree nodes Steffen Druesedow, DTAG, [email protected] 2 Introduction Traditionally, fixed telecommunication operators don t have knowledge about what runs in the customer's local area network (LAN). They provide connectivity and manage the wide area network (WAN) that provides this connectivity, but they do not know anything about the devices and networks behind the gateway (xdsl mainly) that interconnect WAN and LAN. Recently the need for management of customer networks and devices is increasing in order to make the deployment of new complex services at home (home automation, tele-health, VoIP, IPTV, surveillance, etc) feasible with reasonable costs. For example to avoid sending technicians to the customer premises for solving problems. There are two main kinds of devices that need to be managed in operator s business: those which come from the fixed business managed through TR-069 and standardized by the Broadband FORUM, and those which come from the mobile business, managed through OMA-DM and standardized by the Open Mobile Alliance. The DMT Admin specification of OSGi covers the OMA-DM ones. In addition, the design of DMT Admin Service specification potentially allows adaption of other remote management protocols other than the OMA-DM. The best way to realize remote management based on TR-069 on OSGi is utilizing the DMT Admin service. In this case, TR-069 is implemented as a protocol adapter of the DMT Admin. However, there are several architectural differences between the TR-069 and the OMA-DM, although these two protocols have the similar objectives and functionality. Copyright NTT Corporation 2010

335 3 Application Domain RFC-141 DMT Admin Extension Page 7 of 55 Draft 19 November 2010 Driven by triple play service delivery in the home network, fixed line access service providers have the need to configure home devices to ensure the proper service delivery. Broadband Forum s CPE WAN Management Protocol (CWMP, alias TR-069) enables them to do this. By using a remote management server (Auto Configuration Server, ACS), they are able to manage TR-069 enabled devices. TR-069 provides them with possibilities to configure parameters, be informed of parameter changes (notification), start diagnostic tools, update firmware, etc. Similarly, for the mobile world, the OMA defined the OMA-Device Management specification for remote management of mobile devices. OMA-DM offers similar tools to the mobile service providers as TR-069 to fixed line service provider, but OMA-DM is of course tailored to the specifics of the mobile environment. As OSGi technology offers a flexible software environment for all these different devices, the remote management of the platform is of interest for both fixed and mobile service providers. As such, it should be possible to integrate the remote management of the OSGi platform, and the applications running on top of it, in the existing management infrastructure. The DMT Admin service with its mobile management tree in the Mobile specification for OSGi R4 standardizes the remote management of an OSGi platform. As it is largely inspired by OMA-DM, it needs to be evaluated for multi protocol support. 4 Problem Description In a scenario in which service providers offer a growing number of services, to use specific solutions for the management of those services is not the most suitable option. To speed up the deployment of these services, such as triple play, home automation or tele-health, it is essential to offer general management solutions that allow for the management of a large number of services and the flexible life-cycle management of applications. These devices usually are already managed by a standard protocol, so it makes sense that an OSGi framework, which hosts the services, running on a device could be managed in the same way as the other resources of the device. Of course, the remote management should be fully integrated in the existing remote management solutions of the service provider to avoid duplicating management infrastructure and to increase performance on the devices. Currently, there are two options in OSGi for remote management: create a management agent bundle making use of the Java object interfaces, Copyright NTT Corporation 2010

336 RFC-141 DMT Admin Extension Page 8 of 55 Draft 19 November 2010 create a protocol adapter bundle that interacts with the DMT Admin service, as defined in the OSGi Mobile specification. 4.1 Management agent making use of OSGi standardized Java interfaces Currently, for the management of a bundle, the OSGi specifications define different Java objects with which a management application can interact. Using this approach, a management agent can implement extensive management of the OSGi framework, as well as any service standardized. Mapping the Java interfaces to the specific remote management protocol and data model tree is up to the management agent. For runtime interaction with a bundle, a bundle can register a service in the service registry. However, this service interface is not standardized. Also, mapping the service interface to a general management model is not standardized. A current approach is to implement a proprietary service interface on all bundles to be managed. By tailoring this interface so that it easily maps to the management protocol primitives, it is simple for the management agent to map remote management commands to the bundle s service interface. The disadvantage is the proprietary service interface, so that 3rd party bundles might not be compliant. As a conclusion we can say that this current approach allows for extensive remote management of any aspect of the OSGi platform, but lacks a standardized service interface definition for bundles to implement. 4.2 Mobile specification approach The Mobile Expert Group has provided its own solution based on the OMA [3] Device Management [4] specification to provide a remote management solution. The OSGi Mobile specification contains two chapters related to remote management: chapter 3: detailing the mobile management tree chapter 117: detailing: the DMT Admin service, bundle plugin interface specification, the notification service The Device Management Tree model of OMA-DM was chosen as meta-data model and operational model. However, it was intended to be mappable to other protocols. An analysis of mapping the Mobile specification DMT model to TR-069, however, shows that the current DMT model approach (as defined in the OSGi R4 Mobile Specification) introduces some issues. For example: Limitations for active or passive notifications on any parameter in the object tree A limited number of services have been mapped to the DMT model The complexity of mapping a new protocol to the OMA-inspired DMT model, which could imply performance issues on limited devices Support for TR-069 notifications TR-069 offers the feature of active and passive notifications. By setting a parameter s notification attribute, a remote manager requests to be notified with the parameter s new value at the time the value changes (active notification) or at the next periodic inform (passive notification). Notification can be configured on any parameter of the TR-069 object tree. This approach enables the remote manager to be informed not only of changes in status variables of the platform, but also of configuration changes performed by a local manager, e.g. through a local Web interface. The Mobile specification offers a few features that could help to implement TR-069 notification support: Copyright NTT Corporation 2010

337 RFC-141 DMT Admin Extension Page 9 of 55 Draft 19 November 2010 The DMT Admin service sends events using the Event Admin service when operations have been performed on nodes (nodes added, removed or copied; node values changed etc.) The OSGi Notification service defines a way to alert a remote management server. Protocol adaptors on their turn have to implement a RemoteAlertSender interface (and register it) for use by the notification service. Notifications are sent by calling sendnotification on the notification service: The Monitor Admin service: A bundle can register a Monitorable service, to be used by the Monitor Admin service. By registering a Monitorable service, the bundle exposes access to a number of status variables. Notification can be implemented by the StatusVariable provider. If it does, it will call the update method on the Monitor Listener. The Monitor Admin service then generates an event on the Event Admin service. The Monitor service is currently also represented in the DMT. Two problems arise when trying to map the current approach to TR-069: TR-069 defines that notification is applicable to any parameter in the object tree. Currently, the DMT Admin service only send events for operations on DMT nodes that were performed using the DMT Admin API. For example: if configuration changes are performed by using the Configuration Admin service API, no events will be sent. Most of the current implementations do not perform all changes via the DMT Admin service. Therefore, the events sent by the DMT Admin service are an only subset and thus not very reliable as single source of events (and thus as single source of TR-069 notifications). The OSGi Monitor service only supports notification of changes on Status Variables, exposed through a Monitorable service, and enabled by the bundle to support on-change notification (i.e. dynamic Status Variables). Requesting notification is not fully under the control of the remote manager. In the case of a bundle using the notification service, there is no standardized way to configure the bundle to send alerts when the value of one of the implemented DMT nodes changes. In the case of the monitor service, the sending of events can be controlled, but is limited to dynamic Status Variables. The current DMT Admin service has no attributes properties on its nodes to be used to configure notification behavior, such as active notification and passive notification defined in TR-069. Therefore, a remote manager cannot control the notification behavior of DMT nodes in a standardized way. To conclude, the current options, as provided in the Mobile specification, limit notification of parameter changes to StatusVariables, explicitly enabled for monitoring. There is no standardized approach available to monitor changes on any node in the DMT Limitations in the number of services available in the DMT The OSGi R4 Mobile specification mapped a number of services to the DMT. However, these services are limited to the services listed in the Mobile Specification. Other interesting services, as listed in the OSGi R4 Service Compendium are not yet mapped (standardized) in the DMT: The DMT defined in the Mobile Specification contains objects for the following services: Configuration Admin service Log service Copyright NTT Corporation 2010

338 Monitor Admin service Application Admin service RFC-141 DMT Admin Extension Page 10 of 55 Draft 19 November 2010 Conditional Permission Admin service Deployment service A number of areas that could be of interest to a remote manager are currently missing in the DMT: Startlevel management Bundle management: managing individual bundles as opposed to deployment packages (inventory, life-cycle management, exported services, ) Service management: getting a remote view on services registered in the service registry Permission Admin management Home Gateway Core Function management: handling Home Gateway core functions, such as firewall configuration and port forwarding control, from bundles running on an OSGi framework Mapping TR-069 to the OMA-DM inspired DMT model Within the OSGi Mobile specification, the choice has been made to model the DMT after OMA-DM. As a result, creating an OMA-DM protocol adapter is quite straightforward. Although no major hurdles have been identified in creating a TR-069 protocol adapter, it is less straightforward: 1. The TR-069 RPC primitives have to be translated to the DMT Admin service interface methods (which are OMA-DM RPC inspired). 2. The TR-069 tree has to be mapped to the DMT. Translating object model specific features like DMT meta nodes, or TR-069 attributes is not straightforward. It might require specific extensions to the DMT, e.g. to support TR-069 attributes, etc. the TR-069 data types have to be mapped to the DMT Admin data types. However, TR-069 data types, such as unsignedint and datetime (ISO 8601), cannot be translated appropriately into DMT Admin data types defined in the current specification. Translating these data types might result a limitation of the available value range and a complex object that consists of multiple nodes, respectively. 4.3 Management of overlapping trees The DMT Admin has the restrictions that subtrees of configuration data cannot overlap. A DMT Admin Data Plugin that was registered to manage, for example, the sub-tree./internetgatewaydevice receives all requests to data objects below that name. It is not allowed to register a second Data Plugin that, for example, manages the subtree./internetgatewaydevice/wan. Because of this restriction services which register later in time are not allowed to register a Data Plugin to manage the tree or any sub-tree below./internetgatewaydevice. Figure 1 illustrates overlapping subtrees, one of an IGD Data Plugin and the overlapping one, the Vendor IGD Driver Data Plugin that can manage the data model for SomeVendorDevice. Copyright NTT Corporation 2010

339 RFC-141 DMT Admin Extension Page 11 of 55 Draft 19 November I n t e r n e t G a t e w a y D e v i c e... D e v i c e s I G D D a t a P l u g i n... S o m e V e n d o r D e v ic e V e n d o r I G D D r i v e r D a t a P l u g i n Illustration 1: Overlapping Subtrees in DMT Admin A bundle provider can of course register the Data Plugin so that it just registers itself somewhere in the DMT Admin's configuration tree. But in this case, any Management Service that likes to set or access configuration values to or from that bundle does not know the value's path in the configuration tree. 4.4 Management of lists Data models like TR-098 require the ability to map lists of entries to the DMT. The node./internetgatewaydevice.landevice.{i}. is an example for that. There can be more than one LANDevice present in the tree, each of them identified by its own unique id. The DMT Admin has no mechanism specified that provides an automatic generation and management of such unique identifiers to avoid potential name-clashes between different plugins. Such a mechanism must also ensure that a plugin that registers itself gets the same index again, even in case that it was uninstalled/unregistered and then registered again. The mapping of the unique ids to the plugins should be persistent. 4.5 Limitations in Event handling Another restriction concerns the raising of events. The DMT Admin only raises events when a part of the managed configuration is changed via a Data Plugin. A bundle that likes its configuration been managed by the DMT Admin and therefore registers a Data Plugin cannot use the DMT Admin to notify interested bundles if some part of its configuration has changed through other means (low-level event). An example for this is that in an IGD the connection on the WAN interface was established or disconnected. This event arises in the IGD Core Functions layer. The responsible driver bundle can reflect this in its internal configuration mapping, but there are no means to trigger the DMT Admin to raise an event. Copyright NTT Corporation 2010

340 4.6 Conclusion RFC-141 DMT Admin Extension Page 12 of 55 Draft 19 November 2010 The OSGi Mobile specification delivers a standardized data model (the DMT), and standardized interface (on the DMT Admin service) to enable remote management through a protocol adapter. However, the current specification lacks management objects for a number of interesting areas. Also, there is some support lacking for TR-069 notifications. Furthermore, since the DMT model is OMA-DM inspired, implementing a TR-069 protocol adapter is not straightforward, although not impossible. 5 Requirements REQUIREMENT[9]: The solution should be able to handle the data types of unsignedint, unsignedlong, long, hexbinary, datetime (ISO 8601) and nodeuri to accommodate TR-069 protocol. REQUIREMENT[10]: The solution must allow overlapping DataPlugins and overlapping ExecPlugins. REQUIREMENT[11]: The solution must provide a mechanism to generate and manage unique ids for list entries. REQUIREMENT[12]: The solution must allow DataPlugins to send Events for changes in its managed subtree data that where not performed via a DmtSession. 6 Technical Solution This RFC describes how DMT Admin service is extended to accommodate the TR-069 protocol. Since DMT Admin service intends to use the OMA-DM protocol as a remote management protocol, some key features such as data types are missing which makes it difficult to support the TR-069 protocol. This RFC describes the following changes to DMT Admin service. Addition of new data types to DMT Admin service Definition of scaffold nodes Definition of mount points and overlapping of trees Mechanism for lists of plugins Copyright NTT Corporation 2010

341 Extensions for event handling RFC-141 DMT Admin Extension Page 13 of 55 Draft 19 November 2010 minor API-changes for DmtException and There is no need to modify the basic architecture. 6.1 Additional data types Some data types are missing in the DMT Admin specification and are needed to accommodate the TR-069 protocol. The following data types should be added to the format of the DmtData class. FORMAT_LONG A long value. Since there is no suitable data type for unsignedint in Java, this data type should be mapped as unsigned integer for use by the TR-069 protocol. FORMAT_DATETIME A String object that is interpreted as the datetime type defined in ISO 8601; it is used as the value of date and time in TR-069. FORMAT_UNSIGNED_LONG A long value. FORMAT_UNSIGNED_INT An int value. FORMAT_HEXBINARY A byte[] value. FORMAT_NODE_URI A string value. 6.2 Additional system properties The following OSGi environment properties are used to specify the following tree parameters: org.osgi.dmtree.max.segment.name.length This property specifies the maximum allowed length of a URI segment. The value can be requested at runtime via Uri.getMaxSegmentNameLength(). org.osgi.dmtree.max.uri.length This property specifies the maximum allowed length of a URI. The value can be requested at runtime via Uri.getMaxUriLength(). org.osgi.dmtree.max.uri.segments This property specifies the maximum allowed number of Uri segmentss. The value can be requested at runtime via Uri.getMaxUriSegments(). The values for these system properties are immutable after their first initialization. Any subsequent changes of the the system properties after their first initialization are ignored. This RFC does not define any mechanism to specify default or minimum values for the corresponding URI attributes. This is considered as implementation specific. For each of the system properties a corresponding string literal is defined in class info.dmtree.uri (see chapter Definition of constants for literals for details). 6.3 Scaffold nodes Data plugins can be mapped anywhere into the DMT. An ancestor node of a Data Plugin does not necessarily Copyright NTT Corporation 2010

342 RFC-141 DMT Admin Extension Page 14 of 55 need to exist at the time of registration. Draft 19 November 2010 Nevertheless, the DMT Admin must ensure that browse operations in the tree (e.g. starting from the root node. ) are always possible and all mapped plugins are reachable at any point in time. In order to ensure this, the DMT Admin must emulate these missing nodes. Such emulated nodes are called scaffold nodes. All operations of an info.dmtree.spi.readabledatasession must be possible on a scaffold node. Any other operation is forbidden and must lead to a DmtException of error code COMMAND_NOT_ALLOWED. The following table below shows some exemplary cases. The datarooturis in the examples indicate under which URIs the Data Plugins (P1, P2, etc) are registered Meta data of scaffold nodes Scaffold nodes are just structural nodes, which are emulated by the DMT Admin to allow sophisticated mappings of plugins in the DMT. No data plugin is directly responsible for them. That's why it is the DMT Admin who must provide the meta data for them. Following is a description of the values that the meta data for a scaffold node should provide: Operation can() isleaf() getscope() getdescription() GetMaxOccurrence() 1 iszerooccurrenceallowed() getdefault() getvalidnames() getvalidvalues() getmax() getmin() getrawformatnames() getmimetypes() isvalidname() isvalidvalue() Returned value CMD_GET False MetaNode.PERMANENT null true null null null Double.MAX_VALUE Double.MIN_VALUE null null true false getformat() DmtData.FORMAT_NODE - can(): CMD_GET - isleaf(): false - getscope(): MetaNode.PERMANENT - getdescription(): null - getmaxoccurrence(): 1 - iszerooccurrenceallowed(): true Copyright NTT Corporation 2010

343 RFC-141 DMT Admin Extension Page 15 of 55 Draft 19 November getdefault(), getvalidnames(), getvalidvalues(): null - getmax(): Double.MAX_VALUE - getmin(): Double.MIN_VALUE - getrawformatnames(): null - getmimetypes(): null - isvalidname(): true - isvalidvalue(): false - getformat(): DmtData.FORMAT_NODE NOTE: As shown and described later in chapter 6.3 it is possible that the root of a newly registered plugin is mapped to a scaffold node. In such a case, the meta data for this node will not be provided by the DMT Admin anymore but rather by the newly mapped plugin. Please refer to chapter in part "Mounted Plugin registered before Mounting Plugin" for an example and a more detailled description Node type of scaffold nodes The node type of scaffold nodes must be provided by the DMT Admin as URI org.osgi/1.0/scaffoldnode. Therefore it is not allowed and possible that scaffold nodes are list subtree nodes (see also 6.5.1). NOTE: The same remark as for meta data is valid also for the node type. As soon as another plugin is mapped to the scaffold node, this plugin takes over the responsibility for this URI and can return another node type Examples datarooturis Illustration Description P1:./A/B This example maps the root of data plugin P1 to URI./A/B. The node with URI./A is a scaffold node. An invocation of getchildnodenames() on URI./A must return [ B ]. Copyright NTT Corporation 2010

344 RFC-141 DMT Admin Extension Page 16 of 55 P1:./A/B P2:./A/C Draft 19 November 2010 This example maps the root of data plugins P1 to URI./A/B and P2 to URI./A/C The node with URI./A is a scaffold node. An invocation of getchildnodenames() on URI./A must now return [ B, C ]. P1:./A/B P2:./A/C P3:./A/X/Y This example maps the root of data plugins P1 to URI./A/B, P2 to URI./A/C and P3 to URI./A/X/Y The nodes with URIs./A and./a/x are scaffold nodes. An invocation of a getchildnodenames() operation on URI./A must now return [ B, C, X ]. An invocation of a getchildnodenames() operation on URI./A/X must return [ Y ]. Scaffold nodes must be removed by the DMT Admin as soon as they are not required anymore, i.e. when all Data Plugin were unregistered that caused the creation of the scaffold node Scaffold nodes and Events The DmtAdmin must not send Dmt Events when scaffold nodes are created or deleted. 6.4 Mount points Allowing overlapping DMTs can easily lead to quite complex situations. The mount point mechanism is an approach to limit this complexity and to provide a level of control to the implementers of plugins. The main idea behind mount points is that only a plugin itself has the knowledge and the right to define the points in its own subtree where other plugins are allowed to mount themselves. The described mount point mechanisms apply for Data Plugins as well as for Exec Plugins. Copyright NTT Corporation 2010

345 RFC-141 DMT Admin Extension Page 17 of Definitions Draft 19 November 2010 Mount Point: A mount point is a URI relative to the plugin's root. It must not start with a. or /. Mounting Plugin: A mounting plugin is a plugin that defines mount points in its own subtree. Mounted Plugin: A mounted plugin is a plugin that is mapped (mounted) to one of the defined mount points of a mounting plugin. Ancestor Plugin: A plugin P1 is an ancestor plugin of a plugin P2 if P1it is mapped to a URI, which is an ancestor of P2's root URI. Descendant Plugin: A plugin P2 is a descendant plugin of a plugin P1 if P2's root URI is part of the descendants of P1's root URI. Root Plugin: The root plugin is a virtual plugin which is implicitly mapped to the URI.. The root plugin does not specify any mount points. A mapping of a plugin is always possible, if its only ancestor plugin is the root plugin. A Plugin can be a mounting and mounted plugin at the same time. That means it can specify own mount points while being mounted in another plugin's subtree How to specify mount points? Mount points are specified as an optional property during the registration of a plugin. As name for this property the constant info.dmtree.spi.mountplugin.mount_points must be used. The value of this property is an array of Strings, containing the mount point URIs relative to the plugin's datarooturi (its own root ). NOTE: In order to avoid assignment problems, mount points are only allowed if the plugin was registered with exactly one entry in the datarooturis array. If this is not the case and the plugin was registered with the mountpoints property then the plugin registration must be ignored and an error must be logged. Code Example: Dictionary props = new Hashtable(2, 1f); props.put( info.dmtree.spi.dataplugin.data_root_uris, new String[] {./A/B } ); props.put( info.dmtree.spi.mountplugin.mount_points, new String[] { C, E/F } ); context.registerservice( DataPlugin.class.getName(), this, props ); This code registers a Plugin at URI./A/B and specifies that other plugins are allowed to mount themselves under the (absolute) URIs./A/B/C and./a/b/e/f in its own subtree. Illustration Description Copyright NTT Corporation 2010

346 RFC-141 DMT Admin Extension Page 18 of 55 Draft 19 November 2010 A plugin (P1) with datarooturi./a/b was mapped. The plugin has specified a mount point C and E/F. These two nodes are the only points in P1's subtree where other plugins can be mapped. NOTE that these specified mount points are just markers to help the DMT Admin. They are not visible while browsing through the tree. Therefore a call to the getchildnodenames() method on the node with URI./A/B would return an empty array, if no Mounted Plugins for those mount points exist Required checks during plugin mapping When a plugin is registered, then the DMT Admin has to perform several mount-point-related checks before the plugin can be mapped into the DMT. Do the plugins datarooturis point to valid mount points of other plugins? Does the plugin agree with the locations of all direct descendant plugins? The DMT Admin must check that all already mapped descendant plugins conform to the new plugins' mount points. The DMT Admin must perform following checks for each datarooturis of the plugin: 1. Is there already an ancestor plugin mapped except the root plugin? a) if yes: then continue with step 2). b) If not: then continue with step 3). 2. Does the nearest ancestor plugin (i.e. the first mapped plugin that is found, when the tree is traversed upwards from the plugins root) define a mount point that is equal to the plugins datarooturi? a) if yes: then continue with step 3). b) if not: then the plugin cannot be mapped to this datarooturi. This datarooturi is ignored and an error is logged. 3. Are there any descendant plugins for the datarooturi? a) if yes, then continue with step 4). 4. b) if not, then the plugin can be mounted a the given datarooturi without further checks. 5. Does the plugin specify any mount points? Copyright NTT Corporation 2010

347 RFC-141 DMT Admin Extension Page 19 of 55 a) if yes, then continue with step 5). Draft 19 November 2010 NOTE: b) if not, then this datarooturi must be ignored, because it would otherwise tolerate another plugin that it does not agree with. In this case an error must be logged. 6. Is the datarooturi of each descendant plugin matching any of the specified mount points? a) if yes, then the plugin can be mounted at the given datarooturi without further checks. b) if not, then this plugin must be ignored, because it would otherwise tolerate another plugin that it does not agree with. In this case an error must be logged. If a plugin is registered with more than one datarooturi at once, then the above checks are executed for each datarooturi individually. Only those datarooturis which failed the check are ignored and lead to an error log API Extensions Mapping Examples Mounting Plugin registered before Mounted Plugin: Step No. Illustration Description 1 A plugin P1 is registered with: P1: datarooturis: [./A/B] mountpoints: [C] The Plugin P1 is mapped to URI./A/B. The node with URI./A is a scaffold node. The node C is defined as a mount point. The node with URI./A/B/E is a leaf node, managed by P1. Copyright NTT Corporation 2010

348 Step No. Illustration RFC-141 DMT Admin Extension Page 20 of 55 Draft 19 November 2010 Description 2 A second plugin P2 is registered with: P2: datarooturis: [./A/B/C] mountpoints: [ ] The plugin P2 is successfully mapped, because its root URI corresponds to a mount point of P1, i.e. it is valid and P1 agrees with it. 3 A third plugin P3 is registered with: P3: datarooturis: [./A/B/D] mountpoints: [ ] The Plugin is not mapped, because there is no corresponding mount point for the URI./A/B/D. Copyright NTT Corporation 2010

349 Mounted Plugin registered before Mounting Plugin: Step No. Illustration RFC-141 DMT Admin Extension Page 21 of 55 Draft 19 November 2010 Description 1 A plugin P1 is registered with: P1: datarooturis: [./A/B/C] mountpoints: [ ] The Plugin P1 is mapped to URI./A/B/C, because it has no other ancestor than the root node. The nodes with URIs./A and./a/b are scaffold nodes. 2 A second plugin P2 is registered with: P2: datarooturis: [./A/B] mountpoints: [ ] The plugin P2 is not mapped, because it has not specified C (the root of P1) as mount point, i.e. it does not tolerate/agree with P1. That s why it must be ignored and an error must be logged. Copyright NTT Corporation 2010

350 Step No. Illustration RFC-141 DMT Admin Extension Page 22 of 55 Draft 19 November 2010 Description 3 A third plugin P3 is registered with: P3: datarooturis: [./A/B ] mountpoints: [ C, D ] The Plugin is successfully mapped, because it defines the mount point C and therefore agrees with the location of the already mapped plugin P1. Furthermore it defines a second mount point D. NOTE: Until step 2 the node with URI./A/B is a pure scaffold node. The meta data for this node was therefore provided by the DmtAdmin so far. Now P3 was mapped successfully to./a/b. From now on this node is P3's root as well as a scaffold node for P1, otherwise P1 would not be reachable anymore. The meta data for node with URI./A/B however, will now be provided by plugin P3 and can therefore differ from the meta data for the same URI in step Support for lists List Subtree Node List Subtree Node consist of: an interior node that must return the URI info.dmtree.spi.dmtconstants.ddf_list_subtree ( org.osgi/1.0/listsubtree ) as result of its ReadableDataSession.getNodeType method. This URI indicates that this node should be treated as a list of values by a protocol adapter or a local manager. a number of leaf nodes with the same meta data, which represent the individual entries of the list NOTE: Only leaf nodes are allowed as child nodes of the List subtree node. The meta data of the leaf nodes should be provided as follows: a data plugin that wants to support a list subtree node should ensure that meta data for the child leaf nodes of the list are supported, even if no child leaf exists at this point in time. In order to retrieve the meta data for a child leaf node of a list, ANY name can be used as the leaf node name. Example: in order to get the meta data for the elements of the list subtree node with URI./A/B all following invocations of the getmetanode() method are valid: Copyright NTT Corporation 2010

351 RFC-141 DMT Admin Extension Page 23 of 55 Draft 19 November 2010 getmetanode( new String[] {., A, B, 0 } getmetanode( new String[] {., A, B, anyname } getmetanode( new String[] {., A, B, whatever } A Protocol Adapter or Local Manager who wants to modify the value of a list subtree should delete all existing nodes first and then add all new nodes even if any leaf nodes do not change actually. This is intended to avoid expansive intellectual operations using comparisons. When this happens in an atomic session, events will be fired by the DmtAdmin as described in of the DmtAdmin specification Enumerated Plugins (Tables) In order to indicate to the DMT Admin that a data plugin registers itself as an element of an enumeration, an extended syntax rule for the datarooturis is introduced. In such cases the datarooturis must end with a # as placeholder for the index. Note, that # as list indicator is only allowed as last character in the datarooturis. Therefore a plugin that wants to register itself as element of the list InternetGatewayDevice.LANDevice.{i}. in TR-098 has to use the datarooturis./internetgatewaydevice/landevice/#. (see examples section below) NOTE: This syntax must also be used for the definition of mount points to indicate that the mount point is a list. Also here the # is allowed only as last character of the URI. Persistence of assigned IDs The DMT Admin is responsible to assign a unique id and to ensure that the right id is re-used in case that the same plugin is known already. A plugin is considered as known if it uses a known value for the optional registration property service.pid. If a plugin registers without this property then the DMT Admin assigns a free unique id (an id that is not assigned to a currently mapped plugin and not persistently stored yet), but then this id-assignment will not be made persistent. If this plugin is later-on unregistered and registered again, it might get a different id Examples for enumerations of plugins The following examples illustrate the use of the list indicator # in the datarooturis and shows the resulting mappings on an example taken from the TR-098 data model. Copyright NTT Corporation 2010

352 RFC-141 DMT Admin Extension Page 24 of 55 datarooturis and mount points P1: (IGD - Plugin) datarooturi:./internetgatewaydevice mount point: WANDevice/# Illustration Draft 19 November 2010 Description This example maps the root of data plugin P1 to URI./InternetGatewayDevice. P1 furthermore specifies the mount point WANDevice/#, indicating that other plugins are allowed to occupy this place as elements of a list. P2: (DSL Plugin 1) datarooturi:./internetgatewaydevice/w ANDevice/# mount point: WANConnectionDevice/# Plugin P2 is mapped as first list element to P1's mount point. The index 1 has automatically been assigned by the DMT Admin. The resulting root URI of P2 is then:./internetgatewaydevice/wandevice/1 P2 furthermore specifies the mount point WANConnectionDevice/#, indicating that other plugins are allowed to occupy this place as elements of a list. P3: (DSL Plugin 2) datarooturi:./internetgatewaydevice/w ANDevice/# mount point: WANConnectionDevice/# Plugin P3 is mapped as second list element to P1's mount point. The index 2 has automatically been assigned by the DMT Admin. The resulting root URI of P3 is then:./internetgatewaydevice/wandevice/2 P3 furthermore specifies the mount point WANConnectionDevice/#, indicating that other plugins are allowed to occupy this place as elements of a list. Copyright NTT Corporation 2010

353 RFC-141 DMT Admin Extension Page 25 of 55 datarooturis and mount points P4: (ETH Plugin) datarooturi:./internetgatewaydevice/w ANDevice/# mount point: WANConnectionDevice/# Illustration Draft 19 November 2010 Description Plugin P4 is mapped as third list element to P1's mount point. The index 3 has automatically been assigned by the DMT Admin. The resulting root URI of P4 is then:./internetgatewaydevice/wandevice/3 P4 furthermore specifies the mount point WANConnectionDevice/#, indicating that other plugins are allowed to occupy this place as elements of a list. P5: (ATM Plugin) datarooturi:./internetgatewaydevice/w ANDevice/1/WANConnectio ndevice/# mount point: WANPPPConnection/# Plugin P5 is mapped as first list element to P2's mount point. The index 1 has automatically been assigned by the DMT Admin. The resulting root URI of P5 is then:./internetgatewaydevice/wandevice/1/w ANConnectionDevice/1 P5 furthermore specifies the mount point WANPPPConnection/#, indicating that other plugins are allowed to occupy this place as elements of a list. Copyright NTT Corporation 2010

354 RFC-141 DMT Admin Extension Page 26 of 55 datarooturis and mount points P6: (PPP Plugin) datarooturi:./internetgatewaydevice/w ANDevice/1/WANConnectio ndevice/1/wanpppconne ction/# mount point: [] Illustration Draft 19 November 2010 Description Plugin P6 is mapped as first list element to P5's mount point. The index 1 has automatically been assigned by the DMT Admin. The resulting root URI of P6 is then:./internetgatewaydevice/wandevice/1/w ANConnectionDevice/1/WANPPPConnecti on/1 6.6 Extension for event handling Eventing for internal changes in a plugins subtree Changes that influence the state of a plugins subtree can not only occur through a DmtSession but also by low level changes on the plugins data model. There can - for instance - new devices be attached which must be reflected in the data plugins subtree. In the existing specification there is no mechanism defined, that allows a plugin to notify such internal changes to interested entities. This RFC defines a mechanism that also supports internal events. The main difference of internal events compared to normal session based ones is, that internal events don't have an attached session id, because they are caused outside of any session. The details of the mechanism are described in chapter The MountPoint interface. It is strongly recommended that DataPlugins use the postevent() methods of the MountPoint interface to notify internal changes. Using this interface is the only way to ensure that also DmtEventListeners are able to receive such events Eventing for internal changes of list subtrees The described extension is related to DataPlugins which implement lists. As described in chapter 6.5.1, the individual elements of a list are represented as leaf nodes of an interior node of type info.dmtree.spi.dmtconstants.ddf_list_subtree. Copyright NTT Corporation 2010

355 RFC-141 DMT Admin Extension Page 27 of 55 Draft 19 November 2010 This leads to a situation where the outside view on such a node just sees an atomic value while the internal representation is much more granular. It is in the responsibility of the Protocol Adapters (PA) to harmonize both views. If internal changes to the granular elements of a list subtree node happen, then the resulting Events should be the same as for modifications through a DmtSession (see also 6.5.1), i.e. first DELETED, then ADDED etc.. The problem is that the PA needs to know which DmtEvent DELETED and ADDED for siblings belong together and should be assumed as list modification. Otherwise, if for example a TR-069 PA receives one DELETED and one ADDED event for a list subtree node with a notification attribute of active notification, then it could erroneously fire two notifications instead of just one. In order to provide a hint to the event receiver, telling that the current event is just the first one of a pair, a new optional event property is introduced: EVENT_PROPERTY_LIST_UPCOMING_EVENT The only valid value of this property key is true. Furthermore the event property: EVENT_PROPERTY_LIST_NODE is introduced. This property is filled with the URI of the list subtree node and must be indentically in both corresponding events. If an event receiver gets an event of topic info/dmtree/dmtevent/deletedadded with a given property EVENT_PROPERTY_LIST_NODEe and the EVENT_PROPERTY_LIST_UPCOMING_EVENTt set to true, then this receiver should wait for a corresponding event of topic info/dmtree/dmtevent/deletedadded, before it takes the corresponding actions. Example: For explanation, let's assume the following situation: The node "./A/B" has the node type of info.dmtree.spi.dmtconstants.ddf_list_subtree. The leaf node "./A/B/0" has the value of v0, and the leaf node "./A/B/1" has the value of v1. Now, internal change of the list subtree occurs: the list should be set to [v2,v1,v3]. Then two events will be thrown in the following order: info/dmtree/dmtevent/added { nodes = [./A/B/0,./A/B/1,./A/B/2 ] list.node="./a/b" list.upcoming.event="true" } nodes: must contain all node uris as a result of the modification. If no nodes exist, empty array is set. list.node: the internal list node uri list.upcoming.event: indicates that this event is part of a sequence, value must be true info/dmtree/dmtevent/deleted { nodes = [./A/B/0,./A/B/1] list.node="./a/b" Copyright NTT Corporation 2010

356 RFC-141 DMT Admin Extension Page 28 of 55 } nodes: list.node: must be the same as list.node property the internal list node uri Draft 19 November Eventing sequence for atomic sessions The specification in section Event Admin based Events must be improved to make explicitly clear that DmtEvents must not provide information about transaction internal states. That means only those changes that describe the delta between beginning of the session and commit must be signalled as Dmt Events. It is the responsibility of the DmtAdmin to determine this delta and to send the corresponding events Destructive Operations There can be situations where a Protocol Adapter (PA) invokes an operation in a DmtSession which would lead to immediate changes in the framework state, e.g. by setting an appropriate value to the Framework MO that causes the framework to reboot. In such a case it would be impossible for the PA to wait for a proper result for its method invocation and the PA would therefore not be able to respond as required, e.g. to send back a resultresponse to a SetParameterValue request to an ACS. Required is a mechanism that allows the DataPlugin to delay the execution of the destructive operation until it gets a signal that it is safe to perform it. In order to achieve that, a new event topic of name info/dmtree/dmtevent/destructive_operation is introduced. This topic can be used by the DataPlugin for sending events indicating that it intends to perform a desctructive operation, i.e. an operation that can change the state of the system bundle and therefore the whole framework. In contrast to all other internal events that the DataPlugin can emit, this event must be forwarded synchronously to all potential listeners. The listeners (e.g. Protocol Adapters) then have the chance to take the required actions before they return from the handler method. The DataPlugin must wait until the synchronous sending of this event is finished before it can perform its distructive operation. The diagram on the following page shows an exemplary case in form of a message sequence chart. Components that want to register themselves as DmtEventListener must implement the new interface SynchronousDmtEventListener, which inherits from DmtEventListener, otherwise they are not able to receive this synchronous event. It is strongly recommended that DataPlugins use the sendevent() methods of the MountPoint interface to send such events synchronously to potential receivers. Otherwise SynchronousDmtEventListeners will not be able to receive this event. Copyright NTT Corporation 2010

357 Figure 1: Example sequence with a DESTRUCTIVE_OPERATION event

358 RFC-141 DMT Admin Extension Page 30 of 55 Draft 19 November The MountPlugin and MountPoint Interfaces As a consequence of the new possibility to register plugins as elements of lists (by using # in the datarooturi), such plugins don't know their final mapped URI in advance. The list Ids are assigned by the DMT Admin during the mapping process and the plugin has no special means to investigate them. Furthermore plugins can be registered for more than one datarooturi at once, but there can be conditions that cause one or more datarooturi's to be un-mappable at this special point in time. (e.g. if the datarooturi points to a node that has no valid mountpoint in the subtree of another plugin, i.e. it has no corresponding MountingPlugin.) In such cases, not all the datarooturis that the plugin was registered with can be mapped successfully. On the other side there can be conditions that lead to a situation where a datarooturi must be unmapped during runtime, e.g. if the corresponding MountingPlugin was unregistered and therefore also its MountPoints become invalid. The DmtAdmin should provide a way to make plugins aware of these mapping / un-mapping actions, so that they can adapt their behavior accordingly. The remainder of this chapter describes such a mechanism. Nevertheless the plugin needs to know its own mapped URI, for instance if it wants to send events about internal changes in its own subtree, which are not caused by DmtSession operations The MountPlugin interface The mechanism is based on In order to fill this informational gap, a new interface was defined the info.dmtree.spi.mountplugin interface. It can be optionally implemented by a plugins (DataPlugins as well as ExecPlugins). NOTE: The Bundle that wants to make use of the MountPlugin mechanism needs the ServicePermission to register info.dmtree.spi.mountplugin. NOTE: Though the main intention of this new mechanism is to support plugins that are mounted as elements of lists, this is no restriction for their usage. Any plugin can implement and register the MountPlugin interface and use this mechanism, regardless of the occurence of # in its datarooturis. Please also refer to chapter for API details! This interface defines a callback method mountpointsadded( MountPoint[] ), that provides an array of all successfully mapped mount points and a method mountpointsremoved( MountPoint[] ) that informs the plugin about removed mappings. The sequence of operation during plugin registration will be as follows: 1. The plugin developer implements the MountPlugin interface. 2. The plugin is registered with 3 datarooturis (i.e. An array of 3 URI entries) 3. The DMT Admin sees the new Plugin registration and extracts the datarooturis from the registration properties. Copyright NTT Corporation 2010

359 RFC-141 DMT Admin Extension Page 31 of 55 Draft 19 November The DMT Admin loops through the datarooturis and attemps a mapping for each one individually. 5. For each mapping attempt the DMT Admin knows the resulting mapped URI or knows that it has failed. 6. The DMTAdmin checks whether the Plugin was also registered as a MountPlugin. a) if not, then nothing happens b) if yes, then it constructs the MountPoint array with only successfully performed mapping, gets a reference to the MountPlugin interface of the Plugin and invokes the callback mountpointsadded() with this array. The plugin can use the method getmountpath on the provided MountPoints to get the successfully mapped URIs. The sequence of operation when one mapping of the plugin has been removed later in time: 1. Precondition: A plugin was registered with 3 DataRootURI's and two of them where mapped successfully during registration time. 2. Now an ancestor plugin is unregistered and with this also the mount point that justified the plugins mapping has disappeared. 3. As a result, the mapping of the plugin to the disappeared mount point is removed by the Dmt Admin. 4. The DMTAdmin checks whether the Plugin was also registered as a MountPlugin. a) if not, then nothing happens b) if yes, then it constructs the MountPoint array with from the removed URI mapping, gets a reference to the MountPlugin interface of the Plugin and invokes the callback mountpointsremoved() with this array. The sequence of operation when one mapping of the plugin has been added later in time looks similar, except that then the mount points mountpointsadded() method will be invoked The MountPoint interface The new MountPoint interface provides two methods to post events via the DMT Admin. These methods can be used to signal internal changes in the own subtree, that means changes which occurred in their data model without a corresponding DMT Session. (see chapter for furtherapi details) The DmtAdmin is responsible for the actual forwarding of the events. All events that are posted by plugins via the MountPoint interface must be forwarded by the DmtAdmin through the EventAdmin as well as through the changeoccured( DmtEvent ) method of the matching local DmtEventListeners. NOTE: The use of the MountPoint.postEvent() methods is the only possible way for Plugins to signal changes in their internal data to local event listeners! In chapter Eventing for internal changes of list subtrees some new event properties have been introduced Copyright NTT Corporation 2010

360 RFC-141 DMT Admin Extension Page 32 of 55 Draft 19 November 2010 that allow for signalling of internal changes especially for list subtree nodes. Furthermore it was defined that such internal events do not have a session.id property in order to allow a distinction from session event on the receiver side. The existing interface info.dmtree.dmtevent is not prepared to hande these new properties and the fact that the session id can be missing. For that reason the DmtEvent interface is extended as follows (see chapter for API details): a method String[] getpropertynames() is added that allows to infer the names of all event properties a method Object getproperty(string key) is added that allows access to every included property the method int getsessionid() will throw a java.lang.unsupportedoperationexception in case of internal events, where no session id property exists All event properties which are set to Events based on Event Admin are also set to DmtEvent, so that: The properties of nodes can be retrieved by DmtEvent.getNodes() or DmtEvent.getProperty( nodes ). The properties of newnodes can be retrieved by DmtEvent.getNewNodes() or DmtEvent.getProperty( newnodes ). The properties of session.id can be retrieved by DmtEvent.getSessionId() or DmtEvent.getProperty( session.id ). The type can be retrieved only by DmtEvent.getType(). These changes make the usage - pattern for Events based on EventAdmin and Events for DmtEventListeners more aligned to each other. The DMT Admin Service Spec Ver.1.1, Section " Events" should be restructed, in order to reflect those changes and to remove duplicated description for EventAdmin Events and DmtEvents. 6.8 Javadoc Note that only APIs that have been modified and added are included in this document Definition of constants for literals info.dmtree.spi.dataplugin public interface info.dmtree.spi.dataplugin public interface DataPlugin Copyright NTT Corporation 2010

361 RFC-141 DMT Admin Extension Page 33 of 55 Draft 19 November 2010 Field Summary static final DATA_ROOT_URIS String The string to be used as key for the datarooturis property when a DataPlugin is registered. Field Detail DATA_ROOT_URIS public static final String DATA_ROOT_URIS The string to be used as key for the datarooturis property when a DataPlugin is registered. See Also: Constant Field Values info.dmtree.spi.execplugin public interface info.dmtree.spi.execplugin public interface ExecPlugin Field Summary static final EXEC_ROOT_URIS String The string to be used as key for the execrooturis property when an ExecPlugin is registered. Field Detail EXEC_ROOT_URIS public static final String EXEC_ROOT_URIS Copyright NTT Corporation 2010

362 RFC-141 DMT Admin Extension Page 34 of 55 Draft 19 November 2010 The string to be used as key for the execrooturis property when an ExecPlugin is registered. See Also: Constant Field Values info.dmtree.spi.mountplugin public interface info.dmtree.spi.mountplugin public interface MountPlugin Field Summary static final MOUNT_POINTS String The string to be used as key for the mount points property when a DataPlugin or ExecPlugin is registered with mount points. Field Detail MOUNT_POINTS public static final String MOUNT_POINTS The string to be used as key for the mount points property when a DataPlugin or ExecPlugin is registered with mount points. See Also: Constant Field Values info.dmtree.spi.dmtconstants public interface DmtConstants Copyright NTT Corporation 2010

363 Field Summary RFC-141 DMT Admin Extension Page 35 of 55 Draft 19 November 2010 static java.lang.string DDF_LIST_SUBTREE A string defining a DDF URI, indicating that the node is a list subtree. static java.lang.string DDF_SCAFFOLD A string defining a DDF URI, indicating that the node is a scaffold node. static java.lang.string EVENT_PROPERTY_LIST_NODES a string defining the property key for the list.nodes property in node related events static java.lang.string EVENT_PROPERTY_LIST_UPCOMING_EVENT a string defining the property key for the list.upcoming.event property in node related events static java.lang.string EVENT_PROPERTY_NEW_NODES a string defining the property key for the newnodes property in node related events static java.lang.string EVENT_PROPERTY_NODES a string defining the property key for the nodes property in node related events static java.lang.string EVENT_PROPERTY_SESSION_ID a string defining the property key for the session.id property in node related events static java.lang.string EVENT_TOPIC_ADDED a string defining the topic for the event that is sent for added nodes. static java.lang.string EVENT_TOPIC_COPIED a string defining the topic for the event that is sent for copied nodes. static java.lang.string EVENT_TOPIC_DELETED a string defining the topic for the event that is sent for deleted nodes. static java.lang.string EVENT_TOPIC_RENAMED a string defining the topic for the event that is sent for renamed nodes. static java.lang.string EVENT_TOPIC_REPLACED a string defining the topic for the event that is sent for replaced nodes. static java.lang.string EVENT_TOPIC_DESCTRUCTIVE_OPERATION a string defining the topic for the event that can be sent by plugins to indicate their intention to execute a destructive operation that might change the state of the system bundle, i.e. the framework. Field Detail DDF_LIST_SUBTREE static final java.lang.string DDF_LIST_SUBTREE A string defining a DDF URI, indicating that the node is a list subtree. Copyright NTT Corporation 2010

364 RFC-141 DMT Admin Extension Page 36 of 55 See Also: Constant Field Values Draft 19 November 2010 DDF_SCAFFOLD static final java.lang.string DDF_SCAFFOLD A string defining a DDF URI, indicating that the node is a scaffold node. See Also: Constant Field Values EVENT_TOPIC_ADDED static final java.lang.string EVENT_TOPIC_ADDED a string defining the topic for the event that is sent for added nodes. The value of this field is info/dmtree/dmtevent/added. See Also: Constant Field Values EVENT_TOPIC_DELETED static final java.lang.string EVENT_TOPIC_DELETED a string defining the topic for the event that is sent for deleted nodes. The value of this field is info/dmtree/dmtevent/deleted. See Also: Constant Field Values EVENT_TOPIC_REPLACED static final java.lang.string EVENT_TOPIC_REPLACED Copyright NTT Corporation 2010

365 RFC-141 DMT Admin Extension Page 37 of 55 Draft 19 November 2010 a string defining the topic for the event that is sent for replaced nodes. The value of this field is info/dmtree/dmtevent/replaced. See Also: Constant Field Values EVENT_TOPIC_RENAMED static final java.lang.string EVENT_TOPIC_RENAMED a string defining the topic for the event that is sent for renamed nodes. The value of this field is info/dmtree/dmtevent/renamed. See Also: Constant Field Values EVENT_TOPIC_COPIED static final java.lang.string EVENT_TOPIC_COPIED a string defining the topic for the event that is sent for copied nodes. The value of this field is info/dmtree/dmtevent/copied. See Also: Constant Field Values EVENT_TOPIC_DESCTRUCTIVE_OPERATION static final java.lang.string EVENT_TOPIC_DESCTRUCTIVE_OPERATION a string defining the topic for the event that can be sent by plugins to indicate their intention to execute a destructive operation that might change the state of the system bundle, i.e. the framework. The value of this field is info/dmtree/dmtevent/destructive_operation. See Also: Constant Field Values Copyright NTT Corporation 2010

366 RFC-141 DMT Admin Extension Page 38 of 55 Draft 19 November 2010 EVENT_PROPERTY_SESSION_ID static final java.lang.string EVENT_PROPERTY_SESSION_ID a string defining the property key for the session.id property in node related events See Also: Constant Field Values EVENT_PROPERTY_NODES static final java.lang.string EVENT_PROPERTY_NODES a string defining the property key for the nodes property in node related events See Also: Constant Field Values EVENT_PROPERTY_NEW_NODES static final java.lang.string EVENT_PROPERTY_NEW_NODES a string defining the property key for the newnodes property in node related events See Also: Constant Field Values EVENT_PROPERTY_LIST_NODES static final java.lang.string EVENT_PROPERTY_LIST_NODES a string defining the property key for the list.nodes property in node related events See Also: Constant Field Values Copyright NTT Corporation 2010

367 RFC-141 DMT Admin Extension Page 39 of 55 Draft 19 November 2010 EVENT_PROPERTY_LIST_UPCOMING_EVENT static final java.lang.string EVENT_PROPERTY_LIST_UPCOMING_EVENT a string defining the property key for the list.upcoming.event property in node related events See Also: Constant Field Values info.dmtree Class Uri java.lang.object info.dmtree.uri public final class Uri extends java.lang.object Field Summary static java.lang.string MAX_SEGMENT_NAME_LENGTH This property specifies the maximum allowed length of a URI segment. static java.lang.string MAX_URI_LENGTH This property specifies the maximum allowed length of a URI. static java.lang.string MAX_URI_SEGMENTS This property specifies the maximum allowed number of Uri segments. Field Detail MAX_SEGMENT_NAME_LENGTH public static final java.lang.string MAX_SEGMENT_NAME_LENGTH This property specifies the maximum allowed length of a URI segment. This value can be requested at runtime via Uri.getMaxSegmentNameLength(). Copyright NTT Corporation 2010

368 RFC-141 DMT Admin Extension Page 40 of 55 See Also: Constant Field Values Draft 19 November 2010 MAX_URI_LENGTH public static final java.lang.string MAX_URI_LENGTH This property specifies the maximum allowed length of a URI. This value can be requested at runtime via Uri.getMaxUriLength(). See Also: Constant Field Values MAX_URI_SEGMENTS public static final java.lang.string MAX_URI_SEGMENTS This property specifies the maximum allowed number of Uri segments. This value can be requested at runtime via Uri.getMaxUriSegments(). See Also: Constant Field Values Additional Data Types info.dmtree Class DmtData java.lang.object info.dmtree.dmtdata public final class DmtDataextends java.lang.object Field Summary Copyright NTT Corporation 2010

369 RFC-141 DMT Admin Extension Page 41 of 55 Draft 19 November 2010 static int FORMAT_DATETIME The node holds a String object that is interpreted as a datetime type defined in ISO static int FORMAT_HEXBINARY The node holds an hex binary hexbin value. static int FORMAT_NODE_URI The node holds a string value. static int FORMAT_UNSIGNED_INTEGER The node holds an unsigned int value. static int FORMAT_UNSIGNED_LONG The node holds an unsigned long value. Constructor Summary DmtData(byte[] bytes, int format) Create a DmtData instance of the specified format and set its value based on the given byte[]. DmtData(long lng) Create a DmtData instance of long format and set its value. DmtData(java.lang.String value, int format) Create a DmtData instance of the specified format and set its value based on the given string. Method Summary java.lang.string getdatetime() Gets the value of a node with DateTime format. byte[] gethexbinary() Gets the value of a node with hex binary (hexbin) format. long getlong() Gets the value of a node with long (long) format. java.lang.string getnodeuri() Gets the value of a node uri (FORMAT_NODE_URI) format. java.lang.string getunsignedinteger() Gets the value of a node with unsigned integer (uint) format. java.lang.string getunsignedlong() Gets the value of a node with unsigned long (ulong) format. Methods inherited from class java.lang.object clone, finalize, getclass, notify, notifyall, wait, wait, wait Field Detail Copyright NTT Corporation 2010

370 RFC-141 DMT Admin Extension Page 42 of 55 Draft 19 November 2010 FORMAT_LONG public static final int FORMAT_LONG The node holds a long value. The getformatname() method can be used to get the actual format name. See Also: Constant Field Values FORMAT_UNSIGNED_LONG public static final int FORMAT_UNSIGNED_LONG The node holds an unsigned long value. name. See Also: Constant Field Values FORMAT_DATETIME public static final int FORMAT_DATETIME The node holds a String object that is interpreted as a datetime type defined in ISO See Also: Constant Field Values FORMAT_UNSIGNED_INTEGER public static final int FORMAT_UNSIGNED_INTEGER The node holds an unsigned int value. name. See Also: Constant Field Values FORMAT_NODE_URI Copyright NTT Corporation 2010

371 RFC-141 DMT Admin Extension Page 43 of 55 public static final int FORMAT_NODE_URI Draft 19 November 2010 The node holds a string value. This data type should be mapped as String. name. See Also: Constant Field Values FORMAT_HEXBINARY public static final int FORMAT_HEXBINARY The node holds an hex binary hexbin value. The value of the node corresponds to the Java byte[] type. See Also: Constant Field Values Constructor Detail DmtData public DmtData(java.lang.String value, int format) Create a DmtData instance of the specified format and set its value based on the given string. Only the following string-based formats can be created using this constructor: FORMAT_STRING - value can be any string FORMAT_XML - value must contain an XML fragment (the validity is not checked by this constructor) FORMAT_DATE - value must be parseable to an ISO 8601 calendar date in complete representation, basic format (pattern CCYYMMDD) FORMAT_TIME - value must be parseable to an ISO 8601 time of day in either local time, complete representation, basic format (pattern hhmmss) or Coordinated Universal Time, basic format (pattern hhmmssz) FORMAT_DATETIME - value must be parseable to an ISO 8601 definition of a calendar date-time in complete representation, basic format (pattern CCYYMMDDThhmmss) or Coordinated Universal Time, basic format (pattern CCYYMMDDThhmmssZ) FORMAT_UNSIGNED_LONG - value must contain a string that is parsable as unsigned long FORMAT_UNSIGNED_INTEGER - value must contain a string that is parsable as unsigned int FORMAT_NODE_URI - value must contain a string that holds a reference to a node * The null string argument is only valid if the format is string or XML. Parameters: Copyright NTT Corporation 2010

372 RFC-141 DMT Admin Extension Page 44 of 55 Draft 19 November 2010 value - the string, XML, date or time value to set format - the format of the DmtData instance to be created, must be one of the formats specified above Throws: java.lang.illegalargumentexception - if format is not one of the allowed formats, or value is not a valid string for the given format java.lang.nullpointerexception - if a date or time is constructed and value is null DmtData public DmtData(long lng) Create a DmtData instance of long format and set its value. Parameters: lng - the long value to set DmtData public DmtData(byte[] bytes, int format) CCreate a DmtData instance of the specified format and set its value based on the given byte[]. Only the following byte[] based formats can be created using this constructor: FORMAT_BINARY FORMAT_BASE64 FORMAT_HEXBINARY Parameters: bytes - the byte array to set, must not be null format - the format of the DmtData instance to be created, must be one of the formats specified above Throws: java.lang.nullpointerexception - if bytes is null Method Detail getdatetime public java.lang.string getdatetime() Copyright NTT Corporation 2010

373 RFC-141 DMT Admin Extension Page 45 of 55 Draft 19 November 2010 Gets the value of a node with DateTime format. The returned datetime string is formatted according to the ISO 8601 definition of a calendar date-time in complete representation. The exact format depends on the value the object was initialized with: either local time, complete representation, basic format (pattern CCYYMMDDThhmmss) or Coordinated Universal Time, basic format (pattern CCYYMMDDThhmmssZ). Returns: the time value Throws: DmtIllegalStateException - if the format of the node is not time getunsignedinteger public java.lang.string getunsignedinteger() Gets the value of a node with unsigned integer (uint) format. Returns: the unsigned integer value Throws: DmtIllegalStateException - if the format of the node is not integer getlong public long getlong() Gets the value of a node with long (long) format. Returns: the long value Throws: DmtIllegalStateException - if the format of the node is not long getunsignedlong public java.lang.string getunsignedlong() Gets the value of a node with unsigned long (ulong) format. The value is returned as a String because the range of a long is not sufficient to hold the maximum possible unsigned value. Returns: the unsigned long value Throws: DmtIllegalStateException - if the format of the node is not long gethexbinary Copyright NTT Corporation 2010

374 RFC-141 DMT Admin Extension Page 46 of 55 public byte[] gethexbinary() Draft 19 November 2010 Gets the value of a node with hex binary (hexbin) format. Returns: the hex binary value Throws: DmtIllegalStateException - if the format of the node is not hex binary getnodeuri public java.lang.string getnodeuri() Gets the value of a node uri (FORMAT_NODE_URI) format. Returns: the data value in node uri format Throws: DmtIllegalStateException - if the format of the node is not node uri Mount Plugin API info.dmtree.spi Interface MountPlugin public interface MountPlugin This interface can be optionally implemented by a DataPlugin or ExecPlugin in order to get information about its absolute mount points in the overall DMT. This is especially interesting, if the plugin is mapped to the tree as part of a list. In such a case the id for this particular data plugin is determined by the DmtAdmin after the registration of the plugin and therefore unknown to the plugin in advance. Field Summary static java.lang.string MOUNT_POINTS The string to be used as key for the mount points property when a DataPlugin or ExecPlugin is registered with mount points. Copyright NTT Corporation 2010

375 RFC-141 DMT Admin Extension Page 47 of 55 Draft 19 November 2010 Method Summary void mountpointsadded(mountpoint[] mountpoints) Provides the MountPoint objects describing the path where the plugin is mapped to the overall DMT. void mountpointsremoved(mountpoint[] mountpoints) Informs the plugin that the provided MountPoint objects have been removed from the mapping. Field Detail MOUNT_POINTS static final java.lang.string MOUNT_POINTS The string to be used as key for the mount points property when a DataPlugin or ExecPlugin is registered with mount points. See Also: Constant Field Values Method Detail mountpointsadded void mountpointsadded(mountpoint[] mountpoints) Provides the MountPoint objects describing the path where the plugin is mapped to the overall DMT. Parameters: mountpoints - the newly mapped mount points mountpointsremoved void mountpointsremoved(mountpoint[] mountpoints) Informs the plugin that the provided MountPoint objects have been removed from the mapping. NOTE: attempts to invoke one of the postevents on the provided MountPoint will be ignored. Parameters: mountpoints - array of MountPoint objects that have been removed from the mapping Copyright NTT Corporation 2010

376 RFC-141 DMT Admin Extension Page 48 of 55 info.dmtree.spi Interface MountPoint Draft 19 November 2010 public interface MountPoint This interface can be implemented to represent a single mount point. It provides functionalites to get the absolute mounted uri and a shortcut method to post events via the DmtAdmin. Method Summary java.lang.string getmountpath() [] Provides the absolute mount path of this MountPoint void postevent(java.lang.string topic, java.lang.string[] relativeuris, java.util.map properties) Posts an event via the DmtAdmin about changes in the current plugins subtree. void postevent(java.lang.string topic, java.lang.string[] relativeuris, java.lang.string[] newrelativeuris, java.util.map properties) Posts an event via the DmtAdmin about changes in the current plugins subtree. void sendevent(java.lang.string topic, java.lang.string[] relativeuris, java.util.dictionary properties) Sends an event via the DmtAdmin about changes in the current plugins subtree synchronously, i.e. blocking. void sendevent(java.lang.string topic, java.lang.string[] relativeuris, java.lang.string[] newrelativeuris, java.util.dictionary properties) Sends an event via the DmtAdmin about changes in the current plugins subtree synchronously, i.e. blocking. Method Detail getmountpath java.lang.string[] getmountpath() Provides the absolute mount path of this MountPoint Returns: the absolute mount path of this MountPoint Copyright NTT Corporation 2010

377 RFC-141 DMT Admin Extension Page 49 of 55 postevent Draft 19 November 2010 void postevent(java.lang.string topic, java.lang.string[] relativeuris, java.util.map properties) Posts an event via the DmtAdmin about changes in the current plugins subtree. Parameters: topic - the topic of the event to send. Valid values are: info/dmtree/dmtevent/added if the change was cause by a rename action info/dmtree/dmtevent/deleted if the change was cause by a copy action info/dmtree/dmtevent/replaced if the change was cause by a copy action relativeuris - an array of affected node URI's. All URI's specified here are relative to the current MountPoint's mountpath. properties - an optional parameter that can be provided to add properties to the Event that is going to be send by the DMTAdmin postevent void postevent(java.lang.string topic, java.lang.string[] relativeuris, java.lang.string[] newrelativeuris, java.util.map properties) Posts an event via the DmtAdmin about changes in the current plugins subtree. Parameters: topic - the topic of the event to send. Valid values are: info/dmtree/dmtevent/renamed if the change was cause by a rename action info/dmtree/dmtevent/copied if the change was cause by a copy action relativeuris - an array of affected node URI's. All URI's specified here are relative to the current MountPoint's mountpath. newrelativeuris - an array of affected node URI's. This parameter can be null and will only be used if the topics are either info/dmtree/dmtevent/renamed or info/dmtree/dmtevent/copied properties - an optional parameter that can be provided to add properties to the Event that is going to be send by the DMTAdmin Copyright NTT Corporation 2010

378 RFC-141 DMT Admin Extension Page 50 of 55 sendevent Draft 19 November 2010 void sendevent(java.lang.string topic, java.lang.string[] relativeuris, java.util.dictionary properties) Sends an event via the DmtAdmin about changes in the current plugins subtree synchronously, i.e. blocking. Parameters: topic - the topic of the event to send. Valid values are: info/dmtree/dmtevent/added if the change was cause by a rename action info/dmtree/dmtevent/deleted if the change was cause by a copy action info/dmtree/dmtevent/replaced if the change was cause by a copy action relativeuris - an array of affected node URI's. All URI's specified here are relative to the current MountPoint's mountpath. properties - an optional parameter that can be provided to add properties to the Event that is going to be send by the DMTAdmin sendevent void sendevent(java.lang.string topic, java.lang.string[] relativeuris, java.lang.string[] newrelativeuris, java.util.dictionary properties) Sends an event via the DmtAdmin about changes in the current plugins subtree synchronously, i.e. blocking. Parameters: topic - the topic of the event to send. Valid values are: info/dmtree/dmtevent/renamed if the change was cause by a rename action info/dmtree/dmtevent/copied if the change was cause by a copy action relativeuris - an array of affected node URI's. All URI's specified here are relative to the current MountPoint's mountpath. newrelativeuris - an array of affected node URI's. Copyright NTT Corporation 2010

379 RFC-141 DMT Admin Extension Page 51 of 55 Draft 19 November 2010 This parameter can be null and will only be used if the topics are either info/dmtree/dmtevent/renamed or info/dmtree/dmtevent/copied properties - an optional parameter that can be provided to add properties to the Event that is going to be send by the DMTAdmin NOTE: The emitted events will not have a session-id, because the event is low-level and was not produced in the scope of a session DmtException.METADATA_MISMATCH The Javadoc of DmtException.METADATA_MISMATCH must be updated as follows: Section javadoc for DmtException.METADATA_MISTMATCH, where it is stated that it can in an Exception when: "creating, deleting or renaming a permanent node, or modifying its type" DmtException.COMMAND_NOT_ALLOWED Following situation must be added to the Javadoc of DmtException.COMMAND_NOT_ALLOWED in section (public static final int COMMAND_NOT_ALLOWED = 405) an attempt to execute an operation other than the ones defined in info.dmtree.spi.readabledatasession was performed info.dmtree.dmtevent Following extension are required in the javadoc of the interface DmtEvent. Method Summary java.lang.object getproperty(java.lang.string key) This method can be used to get the value of a single event property. java.lang.string getpropertynames() [] This method can be used to query the names of all properties of this event. Copyright NTT Corporation 2010

380 RFC-141 DMT Admin Extension Page 52 of 55 Method Detail Draft 19 November 2010 getsessionid int getsessionid() This method returns the identifier of the session in which this event took place. The ID is guaranteed to be unique on a machine. For events that are result of an internal change inside of a DataPlugin (not in the scope of any session), no sessionid is defined. An invocation of this method on such events will therefore throw an UnsupportedOperationException. The availability of a session.id can also be check by using getproperty() with "session.id" as key. Returns: the unique identifier of the session that triggered the event Throws: java.lang.unsupportedoperationexception - in case that no session id is available. This indicates that the DmtEvent was not a result of a DmtSession. getpropertynames java.lang.string[] getpropertynames() This method can be used to query the names of all properties of this event. The returned names can be used as key value in subsequent calls to getproperty(java.lang.string). Returns: the array of property names See Also: getproperty(java.lang.string) getproperty java.lang.object getproperty(java.lang.string key) This method can be used to get the value of a single event property. Parameters: key - the name of the requested property Returns: the requested property value or null, if the key is not contained in the properties See Also: Copyright NTT Corporation 2010

381 RFC-141 DMT Admin Extension Page 53 of 55 getpropertynames() Draft 19 November Interface info.dmtree.synchronousdmteventlistener info.dmtree Interface SynchronousDmtEventListener All Superinterfaces: DmtEventListener public interface SynchronousDmtEventListenerextends DmtEventListener Like for DmtEventListener, registered implementations of this class are notified via DmtEvent objects about important changes in the tree. The main difference is that implementers of SynchronousDmtEventListener are notified synchronously and therefore blocking. See Also: DmtEventListener Method Summary Methods inherited from interface info.dmtree.dmteventlistener changeoccurred 7 Considered Alternatives Nothing to be described. Copyright NTT Corporation 2010

382 8 Security Considerations RFC-141 DMT Admin Extension Page 54 of 55 Draft 19 November 2010 All security requirements follow the DMT Admin specification. With reference to chapter 6.7 (The MountPlugins and MountPoint interfaces) the following must be stated additionally: When a Plugin invokes one of the postevent methods of the MountPoint interface Mount Plugin API, then the DmtAdmin BundleContext will get the EventAdmin service and no permission is required for the calling bundle except: ServicePermission[ MountPlugin, REGISTER ]. 9 Document Support 9.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. OMA, Open Mobile Alliance. The mission of the Open Mobile Alliance is to facilitate global user adoption of mobile data services by specifying market driven mobile service enablers that ensure service interoperability across devices, geographies, service providers, operators, and networks, while allowing businesses to compete through innovation and differentiation. [4]. OMA Device Management specification v1.2. The goal of the Device Management Working Group is to specify protocols and mechanisms that achieve management of mobile devices including the necessary configuration to access services and management of the software on mobile devices. [5]. CPE WAN Management Protocol, TR-069 amendment 2, December [6]. The Broadband Forum is a global consortium of nearly 200 leading industry players covering telecommunications, equipment, computing, networking and service provider companies. Established in 1994, originally as the ADSL Forum and later the DSL Forum, the Broadband Forum continues its drive for a global mass market for broadband, to deliver the benefits of this technology to end users Copyright NTT Corporation 2010

383 RFC-141 DMT Admin Extension Page 55 of 55 Draft 19 November 2010 around the world over existing copper telephone wire infrastructures. [7]. Data model template for TR-069 enabled devices, TR-106 amendment 1, November Author's Address Name Company Address Koya Mori NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice Name Company Address Ikuo Yamasaki NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice Name Company Address Shigekuni Kondo NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice Acronyms and Abbreviations 9.4 End of Document Copyright NTT Corporation 2010

384 RFC-149 TR-069 Protocol Implementation Guideline Draft 32 Pages Abstract Different industries are interested in applying OSGi to advance their businesses, in which remote management is a key issue. In the residential area, the TR-069 is the one of the de-facto standard protocol for remote management. The best way to realize remote management based on the TR-069 on OSGi is utilizing DMT Admin service, which has been defined in the OSGi Alliance for the mobile device management. In this case, TR-069 is implemented as a protocol adapter of the DMT Admin. The DMT Admin service, however, has the interfaces inspired by OMA-DM, which is the de-facto standard protocol for mobile area. Although these two protocols, the TR-069 and the OMA-DM, have the similar objectives and functionality, there are several differences between them. This RFC introduces the guideline of the mapping between TR-069 RPCs and the DMT Admin interfaces, and the guideline of data type translation. Copyright NTT Corporation 2010 This contribution is made to the OSGi Alliance as MEMBER LICENSED MATERIALS pursuant to the terms of the OSGi Member Agreement and specifically the license rights and warranty disclaimers as set forth in Sections 3.2 and 12.1, respectively. All company, brand and product names contained within this document may be trademarks that are the sole property of the respective owners. The above notice must be included on all copies of this document that are made.

385 RFC-149 TR-069 Protocol Implementation Guideline Page 2 of 32 1 Document Information Draft 9 October Table of Contents 1 Document Information Table of Contents Terminology and Document Conventions Revision History Introduction Application Domain Problem Description Management agent making use of OSGi standardized Java interfaces Mobile specification approach Support for TR-069 notifications Conclusion Requirements Technical Solution Basic architecture of TR-069 protocol implementation RPC mapping for TR TR-069 CPE RPCs to DMT Admin Interfaces DMT Admin Interfaces to TR-069 ACS RPCs Session management Opening Session Commit for Atomic Session Mapping of data types Mapping for GetParameterValues RPC Mapping for SetParameterValues RPC Error code and SOAP Fault Error code and Fault code mapping SOAP Fault expression Javadoc org.osgi.util.tr069 Class TR069ParameterValue TR069DATATYPE_INT TR069DATATYPE_UNSIGNED_INT TR069DATATYPE_LONG TR069DATATYPE_UNSIGNED_LONG TR069DATATYPE_STRING TR069DATATYPE_BOOLEAN Copyright NTT Corporation 2010

386 RFC-149 TR-069 Protocol Implementation Guideline Page 3 of 32 Draft 9 October TR069DATATYPE_BASE TR069DATATYPE_HEXBINARY TR069DATATYPE_DATETIME TR069ParameterValue getvalue gettype getdmtdata getdmtdatasforlist gettr069parametervalueforlist gettr069parametervalue org.osgi.util.tr069 Class TR069URI getdmturi gettr069path isvalidtr069path Considered Alternatives Future work for notification handling Future work for forced inform parameters Security Considerations Document Support References Author's Address Acronyms and Abbreviations End of Document Terminology and Document Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in Source code is shown in this typeface. 1.3 Revision History The last named individual in this history is currently responsible for this document. Revision Date Comments Initial Sep Initial Draft Koya Mori, NTT Corporation, [email protected] Copyright NTT Corporation 2010

387 RFC-149 TR-069 Protocol Implementation Guideline Page 4 of 32 Revision Date Comments 2nd Jan nd Draft 3rd Jun rd Draft 4th Jul th Draft 5th Sep th Draft Oct th Draft Draft 9 October 2010 Generic setter/getter methods are added. Limitation of notification is described. Koya Mori, NTT Corporation, [email protected] The technical solution has been changed to describe guideline of RPC mapping for TR-069. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] The detail of the Notification handling and the RPC mapping is defined. And the Session Management is added. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] The number of this RFC has been changed to 148. The behavior for notification and session management is changed based on the REG F2F discussion. The error code mapping is added. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] The number of this RFC has been changed to 149. Notification handling is changed based on REG discussion. The operation for forced inform parameter is added. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Copyright NTT Corporation 2010

388 RFC-149 TR-069 Protocol Implementation Guideline Page 5 of 32 Revision Date Comments Jan th Draft Apr th Draft Oct th Draft Draft 9 October 2010 Two implementation models are added to allow the RFC-145. Forced inform parameters handling mechanism is added. Notification event definition is changed to use multiple events. The data mapping is fixed to accommodate the new data types. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Based on the discussion of REG F2F in Mountain View, the following modifications are done; abstract was modified. some descriptions which has no relationships with what this RFC provides technically are removed in Section 4. Requirements which this RFC cannot meet are removed in Section 5. all descriptions of concrete solutions on notifications and forced inform parameters are removed in Section 6. Section 7.1 and 7.2 are added for future work on notification and forced inform parameters, respectively. Koya Mori, NTT Corporation, [email protected] Ikuo Yamasaki, NTT Corporation, [email protected] Based on the discussion of REG F2F, June and August, and discussion on ML and Bugzilla, the following modifications are done; Section 6.4 Mapping of data types was completely updated. Details of mapping SetParameterValues RPC and GetParameterValues RPC is added in Section Javadoc for the utility class is added in Section 7. Ikuo Yamasaki, NTT Corporation, [email protected] Copyright NTT Corporation 2010

389 2 Introduction RFC-149 TR-069 Protocol Implementation Guideline Page 6 of 32 Draft 9 October 2010 Traditionally, fixed telecommunication operators don t have knowledge about what runs in the customer's local area network (LAN). They provide connectivity and manage the wide area network (WAN) that provides this connectivity, but they do not know anything about the devices and networks behind the gateway (xdsl mainly) that interconnect WAN and LAN. Recently the need for management of customer networks and devices is increasing in order to make the deployment of new complex services at home (home automation, tele-health, VoIP, IPTV, surveillance, etc) feasible with reasonable costs. There are two main kinds of devices that need to be managed in operator s business: those which come from the fixed business managed through TR-069 and standardized by the Broadband FORUM, and those which come from the mobile business, managed through OMA-DM and standardized by the Open Mobile Alliance. The DMT Admin Service specification of OSGi covers the OMA-DM ones. In addition, the design of DMT Admin Service specification potentially allows adaption of other remote management protocols other than the OMA-DM. The best way to realize remote management based on TR-069 on OSGi is utilizing the DMT Admin service. In this case, TR-069 is implemented as a protocol adapter of the DMT Admin. However, there are several architectural differences between the TR-069 and the OMA-DM, although these two protocols have the similar objectives and functionality. Therefore, this RFC defines the mapping guideline between the TR-069 and the DMT Admin to use them together. In addition, this RFC defines the handling of notification mechanism and data type translation. 3 Application Domain Driven by triple play service delivery in the home network, fixed line access service providers have the need to configure home devices to ensure the proper service delivery. Broadband Forum s CPE WAN Management Protocol (CWMP, alias TR-069) enables them to do this. By using a remote management server (Auto Configuration Server, ACS), they are able to manage TR-069 enabled devices. TR-069 provides them with possibilities to configure parameters, be informed of parameter changes (notification), start diagnostic tools, update firmware, etc. Similarly, for the mobile world, the OMA defined the OMA-Device Management specification for remote management of mobile devices. OMA-DM offers similar tools to the mobile service providers as TR-069 to fixed line service provider, but OMA-DM is of course tailored to the specifics of the mobile environment. As OSGi technology offers a flexible software environment for all these different devices, the remote management of the platform is of interest for both fixed and mobile service providers. As such, it should be possible to integrate the remote management of the OSGi platform, and the applications running on top of it, in the existing management infrastructure. Copyright NTT Corporation 2010

390 RFC-149 TR-069 Protocol Implementation Guideline Page 7 of 32 Draft 9 October 2010 The DMT Admin service with its mobile management tree in the Mobile specification for OSGi R4 standardizes the remote management of an OSGi platform. As it is largely inspired by OMA-DM, it needs to be evaluated for multi protocol support. 4 Problem Description In a scenario in which service providers offer a growing number of services, to use specific solutions for the management of those services is not the most suitable option. To speed up the deployment of these services, such as triple play, home automation or tele-health, it is essential to offer general management solutions that allow for the management of a large number of services and the flexible life-cycle management of applications. These devices usually are already managed by a standard protocol, so it makes sense that an OSGi framework, which hosts the services, running on a device could be managed in the same way as the other resources of the device. Of course, the remote management should be fully integrated in the existing remote management solutions of the service provider to avoid duplicating management infrastructure and to increase performance on the devices. Currently, there are two options in OSGi for remote management: create a management agent bundle making use of the Java interfaces, create a protocol adapter bundle that interacts with the DMT Admin service, as defined in the OSGi Mobile specification. 4.1 Management agent making use of OSGi standardized Java interfaces Currently, for the management of a bundle, the OSGi specifications define different Java objects with which a management application can interact. Using this approach, a management agent can implement extensive management of the OSGi framework, as well as any service standardized. Mapping the Java interfaces to the specific remote management protocol and data model tree is up to the management agent. For runtime interaction with a bundle, a bundle can register a service in the service registry. However, this service interface is not standardized. Also, mapping the service interface to a general management model is not standardized. A current approach is to implement a proprietary service interface on all bundles to be managed. By tailoring this interface so that it easily maps to the management protocol primitives, it is simple for the management agent to map remote management commands to the bundle s service interface. The disadvantage is the proprietary service interface, so that 3rd party bundles might not be compliant. As a conclusion we can say that this current approach allows for extensive remote management of any aspect of the OSGi platform, but lacks a standardized service interface definition for bundles to implement. Copyright NTT Corporation 2010

391 4.2 Mobile specification approach RFC-149 TR-069 Protocol Implementation Guideline Page 8 of 32 Draft 9 October 2010 The Mobile Expert Group has provided its own solution based on the OMA [3] Device Management [4] specification to provide a remote management solution. The OSGi Mobile specification contains two chapters related to remote management: chapter 3: detailing the mobile management tree chapter 117: detailing: the DMT Admin service, bundle plugin interface specification, the notification service The Device Management Tree model of OMA-DM was chosen as meta-data model and operational model. However, it was intended to be mappable to other protocols. An analysis of mapping the Mobile specification DMT model to TR-069, however, shows that the current DMT model approach (as defined in the OSGi R4 Mobile Specification) introduces some issues. For example: Limitations for active or passive notifications on any parameter in the object tree The complexity of mapping a new protocol to the OMA-inspired DMT model, which could imply performance issues on limited devices Support for TR-069 notifications TR-069 offers the feature of active and passive notifications. By setting a parameter s notification attribute, a remote manager requests to be notified with the parameter s new value at the time the value changes (active notification) or at the next periodic inform (passive notification). Notification can be configured on any parameter of the TR-069 object tree. This approach enables the remote manager to be informed not only of changes in status variables of the platform, but also of configuration changes performed by a local manager, e.g. through a local Web interface. The Mobile specification offers a few features that could help to implement TR-069 notification support: The DMT Admin service sends events using the Event Admin service when operations have been performed on nodes (nodes added, removed or copied; node values changed etc.) The OSGi Notification service defines a way to alert a remote management server. Protocol adapters on their turn have to implement a RemoteAlertSender interface (and register it) for use by the notification service. Notifications are sent by calling sendnotification on the notification service: The Monitor Admin service: A bundle can register a Monitorable service, to be used by the Monitor Admin service. By registering a Monitorable service, the bundle exposes access to a number of status variables. Notification can be implemented by the StatusVariable provider. If it does, it will call the update method on the Monitor Listener. The Monitor Admin service then generates an event on the Event Admin service. The Monitor service is currently also represented in the DMT tree. Two problems arise when trying to map the current approach to TR-069: TR-069 defines that notification is applicable to any parameter in the object tree. Currently, the DMT Admin service only send events for operations on DMT nodes that were performed using the DMT Admin API. The DMT Admin Spec does not require Data Plugins to send events when DMT nodes are changed through except the DMT Admin API. It is called internal changes hereafter. For example: if configuration changes are performed by using the Configuration Copyright NTT Corporation 2010

392 RFC-149 TR-069 Protocol Implementation Guideline Page 9 of 32 Draft 9 October 2010 Admin service API, there might be no events sent. Such internal changes should be supported for TR-069 notification. However, it cannot be supported. The OSGi Monitor service only supports notification of changes on Status Variables, exposed through a Monitorable service, and enabled by the bundle to support on-change notification (i.e. dynamic Status Variables). Requesting notification is not fully under the control of the remote manager. In the case of a bundle using the notification service, there is no standardized way to configure the bundle to send alerts when the value of one of the implemented DMT nodes changes. In the case of the monitor service, the sending of events can be controlled, but is limited to dynamic Status Variables. The current DMT Admin service has no attributes properties on its nodes to be used to configure notification behavior, such as active notification and passive notification defined in TR-069. Therefore, a remote manager cannot control the notification behavior of DMT nodes in a standardized way. To conclude, the current options, as provided in the Mobile specification, limit notification of parameter changes to StatusVariables, explicitly enabled for monitoring. There is no standardized approach available to monitor changes on any node in the DMT Mapping TR-069 to the OMA-DM inspired DMT model Within the OSGi Mobile specification, the choice has been made to model the DMT after OMA-DM. As a result, creating an OMA-DM protocol adapter is quite straightforward. Although no major hurdles have been identified in creating a TR-069 protocol adapter, it is less straightforward: The TR-069 RPC primitives have to be translated to the DMT Admin service interface methods (which are OMA-DM RPC inspired). The TR-069 data types have to be mapped to the DMT Admin data types. However, TR-069 data types, such as unsignedint and datetime (ISO 8601), cannot be translated appropriately into DMT Admin data types defined in the current specification. Translating these data types might result a limitation of the available value range and a complex object that consists of multiple nodes, respectively. 4.3 Conclusion The OSGi Mobile specification delivers a standardized data model (the DMT), and standardized interface (on the DMT Admin service) to enable remote management through a protocol adapter. However, in the current specification there is some support lacking for TR-069 notifications. Furthermore, since the DMT model is OMA- DM inspired, implementing a TR-069 protocol adapter is not straightforward, although not impossible. Copyright NTT Corporation 2010

393 5 Requirements RFC-149 TR-069 Protocol Implementation Guideline Page 10 of 32 Draft 9 October 2010 REQUIREMENT[8]: The solution should specify a guideline of RPC mapping between DMT Admin service interfaces and remote management protocols, such as TR Technical Solution This RFC provides a guideline for RPC mapping between DMT Admin service interfaces and TR-069 protocol, which is defined by Broadband Forum [6]. Since the DMT Admin service focuses on the OMA-DM protocol for remote management, some features, such as RPC mapping and notification mechanism, are inadequate in terms of supporting the TR-069 protocol. This RFC makes the following recommendations to support TR-069. Guideline mapping between the DMT Admin interfaces and TR-069 protocol RPCs Management of sessions including read-only and transactional session Data type mapping not defined in the DMT Admin specification version 1.0 Error code mapping and SOAP Fault handling for TR-069 protocol The basic architecture of DMT Admin service does not need to be modified to support the TR-069 protocol. Therefore, only the specifications and APIs that are related to the above recommendations are included in this document. Copyright NTT Corporation 2010

394 RFC-149 TR-069 Protocol Implementation Guideline Page 11 of 32 Draft 9 October Basic architecture of TR-069 protocol implementation The basic architecture of a system using TR-069 follows that defined in DMT Admin specification (see Figure 1). In the architecture, there must be a protocol adapter that uses the TR-069 protocol to communicate with remote manager. On the other hand, each data model, which is intended to be managed through the protocol adapter, must be implemented as a data plugin for DMT Admin service. Fig.1 Basic Architecture of TR-069 Protocol Implementation The TR-069 protocol adapter should call DmtSession interface provided by DMT Admin service when the remote manager calls some particular protocol adapter's RPCs specified by TR-069. Data plugins are used to implement the data models that are to be manipulated via the interfaces defined in the DMT Admin specification. Therefore, a remote manager's operation through the TR-069 protocol can be propagated to the data plugins. On the other hand, notifications from data plugins to remote managers are propagated through DMT Admin and TR-069 protocol adapter. There are two possible ways to send notifications to the TR-069 protocol adapter; the first one is using the Notification Service registered by the DMT Admin, and the second one is using the Event Admin. In the first case, the data plugin gets the services and calls the method to send a notification. The Remote Alert Sender service registered by the TR-069 protocol adapter will receive it. In the second case, the data plugin gets the Event Admin service and calls the method to fire a event and the Event Handler service registered by the TR-069 protocol adapter will receive it. Then, the TR-069 protocol adapter should send the TR-069 notification to the remote manager properly. 6.2 RPC mapping for TR-069 DMT Admin interface is not restricted to any specific protocol but is inspired by the RPCs of OMA-DM, because OMA-DM is a primary remote management protocol for the mobile industry. In TR-069 specification, there are 17 RPCs for handling client devices, which include basic setter / getter methods and methods modifying tree-structured data. Although these RPCs are very similar to OMA-DM RPCs, there is a slight mismatch between TR-069 RPCs and the methods defined by the DMT Admin specification. Copyright NTT Corporation 2010

395 RFC-149 TR-069 Protocol Implementation Guideline Page 12 of 32 Draft 9 October 2010 Therefore, mapping rules between them should be defined in order to manipulate data models properly such as the Residential Management Model defined in RFC-140. This RFC provides the guidelines; how an implementation of TR-069 protocol adapter should call one or more DMT Admin methods, when it receives TR-069 RPCs from a remote manager, and how an implementation of TR-069 protocol adapter should call one or more TR-069 RPCs, when it receives DMT Admin methods callback, originated by Data Plugins TR-069 CPE RPCs to DMT Admin Interfaces Table 1 shows the mapping guideline of TR-069 CPE RPCs to DMT Admin interfaces. TR-069 CPE RPCs are the RPCs implemented in the client side program and called by a remote server. TR-069 protocol adapter, therefore, calls DMT Admin service through the DmtSession interface. Table 1:Mapping of TR-069 CPE RPCs to DMT Admin interfaces Type TR-069 RPCs DMT Admin methods Remarks TR-069 CPE required RPC GetRPCMethods None There is no recommendation for these RPCs. These RPCs' action depends on the implementation of the protocol adapter. GetParameterValues See See SetParameteValues See See GetParameterNames DmtSession.getEffec tivenodeacl() SetParameterAttribut es GetParameterAttribut es AddObject DmtSession.getChild NodeNames() None None DmtSession.createIn teriornode() DmtSession.getChild This RPC is used to obtain parameters of the specified path. Therefore, DmtSession.getChildNodeNames() should be called to get the node name as a parameter name. Because the obtained information includes the permission for overwriting the specified node, DmtSession.getEffectiveNodeAcl() should be also used to get the information. These methods should be called recursively for all of the nodes in the sub-tree indicated by the parameter path. CPE should return the GetParameterNamesResponse after completion of all method calls for the arguments. If the protocol adapter encounters the DmtException with PERMISSION_DENIED code, it should continue operation for getting the next node name and should discard the DmtException. There is no recommendation for these RPCs. These RPCs' action depends on the implementation of the protocol adapter. This RPC is used to create an object sub-tree including interior nodes and leaf nodes, and only interior node indicating object name, which is Copyright NTT Corporation 2010

396 RFC-149 TR-069 Protocol Implementation Guideline Page 13 of 32 Draft 9 October 2010 Type TR-069 RPCs DMT Admin methods Remarks TR-069 CPE optional RPC DeleteObject NodeNames() DmtSession.deleteN ode() usually the node locating at the top of sub-tree hierarchy, can be specified. At first, the protocol adapter should call DmtSession.getChildNodeNames() to get instance IDs currently existing to check the instance IDs which is created by the data plugin internally. Second, the protocol adapter chooses one instance ID that has been never used before, which means the instance ID must not be reused for the same object beyond reboots of an OSGi framework. The protocol adapter should then call the DmtSession.createInteriorNode() with the specified path name and the selected instance ID, and the data plugin tries to create the desired object under the indicated instance ID. If the indicated ID is not acceptable for the data plugin, for example the ID is already used by the data plugin internally or the ID is reserved to create instance in the future, the data plugin must throw DmtException with COMMAND_FAILED code to the protocol adapter. If the DmtException is thrown, the protocol adapter should change the instance ID and should retry the creation of the object by calling DmtSession.createInteriorNode() until the prescribed number of times has been exceeded. Finally, the protocol adapter must return the AddObjectResponse with the instance ID to the remote manager if the operation succeeded. [Remarks] A data plugin may give the same instance ID to the same target in order to keep consistency of the node path, if the instance is created by not the operation from the protocol adapter but by the data plugin internally. This RPC is to delete the specified object including interior and leaf nodes. Therefore, the DmtSession.DeleteNode() should be called with the instance ID of the object, which is specified as the parameter of DeleteObject RPC. Reboot None There is no recommendation for these RPCs. Download None These RPCs' action depends on the implementation of the protocol adapter. ScheduleInform None This RPC is not related to DMT Admin method. Therefore, there is no recommendation for this RPC. FactoryReset None There is no recommendation for these RPCs. These RPCs' action depends on the GetQueuedTransfers None implementation of the protocol adapter. Upload None SetVouchers None Copyright NTT Corporation 2010

397 RFC-149 TR-069 Protocol Implementation Guideline Page 14 of 32 Draft 9 October 2010 Type TR-069 RPCs DMT Admin methods Remarks GetOptions None Mapping of GetParameterValues RPC to DMT Admin Interfaces When a TR-069 Protocol Adapter receives GetParameterValues RPC, it will handle each requested Parameter names as followings: 1. The TR-069 Protocol Adapter judges whether a Parameter name is partial path name or not. It can be done by checking if name ends with. (dot) or not. If it is partial path name, the Protocol Adapter needs to return all of the Parameters in the branch of the naming hierarchy that shares the same prefix as the argument. For each name requested, the followings procedure Step 2 to Step 8 will be done: 2. The TR-069 Protocol Adapter gets the node URI corresponding to the requested name by calling TR069URI.getDmtUri() with the name, the TR-069 path. The Protocol Adapter can check whether the name is valid TR-069 path by calling TR069URI.isValidTR069Path(). 3. The TR-069 Protocol Adapter opens DmtSession against the node URI as described in The Protocol Adapter calls DmtSession.getNodeType() with the node URI and if the node type is org.osgi/1.0/listsubtree, go to step 5. Otherwise go to step The Protocol Adapter gets the list of DmtData of all child leaf nodes of the node by DmtSession.getChildNodeNames() and DmtSession.getNodeValue(). Then it calls TR069ParameterValue.getTR069ParameterValueForList(). The method returns TR069ParameterValue instance. Go to step The Protocol Adapter gets the DmtData of nodes by DmtSession.getNodeValue() and calls TR069ParameterValue.getTR069ParameterValue() with it. The method returns TR069ParameterValue instance. Go to step The TR-069 Protocol Adapter uses the data type and the value, which the returned TR069ParameterValue contains, for GetParameterValuesResponse RPC to ACS. 8. If the TR-069 Protocol Adapter encounters the Exception in the procedure from Step2 to 7, the protocol adapter should keep the Exception information but continue operation for the next name requested. 9. After all requested ParameterValueStruct are handled, the TR-069 Protocol Adapter will send GetParameterValuesResponse RPC to the ACS. The RPC must contains appropriate SOAP Faults corresponding to all Exception information kept in Step Mapping of SetParameterValues RPC to DMT Admin Interfaces When a TR-069 Protocol Adapter receives SetParameterValues RPC, it will handle each requested ParameterValueStruct as followings: Copyright NTT Corporation 2010

398 RFC-149 TR-069 Protocol Implementation Guideline Page 15 of The TR-069 Protocol Adapter retrieves the value as String and the type. Draft 9 October The TR-069 Protocol Adapter gets the node URI corresponding to the requested TR-069 path by calling TR069URI.getDmtUri() with the path name. The Protocol Adapter can check whether the name is valid TR-069 path by calling TR069URI.isValidTR069Path(). 3. The TR-069 Protocol Adapter opens DmtSession against the node URI as described in The TR-069 Protocol Adapter finds the character set name specified as its SOAP request encoding. 5. The Protocol Adapter calls DmtSession.getNodeType() with the node URI and if the type of the node is org.osgi/1.0/listsubtree, go to step 6. Otherwise go to step The TR-069 Protocol Adapter gets the MetaNode object of the child node of the specified node URI by DmtSession.getMetaNode() and calls TR069ParameterValue.getDmtDatasForList() with the value, the TR-069 type, the character set name, the node URI and the retrieved MetaNode. The method returns array of DmtData. For each element, the TR-069 Protocol Adapter sets the DmtData to the child node of the specified node URI. The first element of the array of DmtData will be set to the node name 1 and the node name will be incremented one by one. If the node does not exist, DmtSession.createLeafNode() is used. How to handle existing node depends on the implementation. For instance, deleting all child nodes by DmtSession.deleteNode() and creating new all child nodes by DmtSession.createLeafNode() is one way. Go to Step The TR-069 Protocol Adapter gets the MetaNode object of the specified node URI by DmtSession.getMetaNode(). Then it calls TR069ParameterValue.getDmtData() with the value, the TR- 069 type, the character set name, the node URI and the retrieved MetaNode. The method returns an DmtData. The TR-069 Protocol Adapter sets the DmtData to the specified node URI. Go to Step If the protocol adapter encounters the Exception in the procedure from Step2 to 7, the protocol adapter should keep the Exception information but continue operation for the next requested ParameterValueStruct. 9. After all requested ParameterValueStruct are handled, the TR-069 Protocol Adapter will send SetParameterValuesResponse RPC to the ACS. The RPC must contains appropriate SOAP Faults corresponding to all Exception information kept in Step DMT Admin Interfaces to TR-069 ACS RPCs Table 2 shows the mapping guideline of DMT Admin interfaces to TR-069 ACS RPCs. TR-069 ACS RPCs are the RPCs implemented in the server side program and called by a managed client. Therefore, the TR-069 protocol adapter should call TR-069 ACS RPCs when the DMT Admin calls the TR-069 protocol adapter through the RemoteAlertSender interface. A protocol adapter must register the RemoteAlertSender service, which is defined in the DMT Admin specification, with the principals service property that represents the associated principals of the protocol adapter. Table 2:Mapping of TR-069 ACS RPCs to DMT Admin interfaces Type DMT Admin methods TR-069 RPCs Remarks TR-069 ACS required RPC RemoteAlertSender.s endalert() Inform A protocol adapter must register the RemoteAlertSender service with the principals Copyright NTT Corporation 2010

399 RFC-149 TR-069 Protocol Implementation Guideline Page 16 of 32 Draft 9 October 2010 Type DMT Admin methods TR-069 RPCs Remarks TR-069 ACS optional RPC property that represents the associated principals of the protocol adapter. When the RemoteAlertSender.sendAlert() implemented by the protocol adapter is called, the Inform RPC should be fired to the associated ACS. The code specified as the parameter of the method should be interpreted as the EventCode included in the EventStruct defined in the TR-069 specification. And the ParameterList that is contained in the Inform RPC should include the ParameterValueStruct consisting of the Name and Value, which should be the source and the data included in the AlertItem, respectively. If the AlertItem does not contain any source as the node that is the cause of the alert, the protocol adapter should discard the AlertItem and does not have to send Inform RPC. Note that this definition intends to implement scenarios in which an alert emerges from data plugins. Therefore, other use cases, such as Periodic, Boot and TransferComplete, should be implemented on an user-defined way. None TransferComplete There is no recommendation for these RPCs. This RPC's action depends on the implementation of the protocol adapter. None GetRPCMethods There is no recommendation for these RPCs. These RPCs' action depends on the None AutonomousTransfer implementation of the protocol adapter. Complete None RequestDownload 6.3 Session management Opening Session The DMT Admin specification defines three types of locking modes of sessions for protocol adapters to open a DmtSession for reading or writing node values; LOCK_TYPE_SHARED, LOCK_TYPE_EXCLUSIVE and LOCK_TYPE_ATOMIC, which correspond to the ReadableDataSession, the ReadWriteDataSession and the TransactionalDataSession respectively. The protocol adapter adaptively chooses either LOCK_TYPE_ATOMIC or LOCK_TYPE_EXCLUSIVE as the lock mode based on the RPC, when it receives the SOAP request from the remote manager. If the received RPC needs to write node values, the protocol adapter must use LOCK_TYPE_ATOMIC session. If there already exists an opened LOCK_TYPE_ATOMIC session, the session will continue to be used. Otherwise, the protocol adapter should open a new session as LOCK_TYPE_ATOMIC. If the received RPC does not need to write node values, the protocol adapter should use LOCK_TYPE_SHARED session. If there already exists an opened LOCK_TYPE_SHARED session, the session will continue to be used. Otherwise, the protocol adapter should open a new session as LOCK_TYPE_SHARED. Copyright NTT Corporation 2010

400 RFC-149 TR-069 Protocol Implementation Guideline Page 17 of 32 Draft 9 October 2010 On the other hand, the timing of closing session is not defined in this RFC. The close of the session should be conducted in a reasonable way depends on the implementation. In general, the protocol adapter should avoid opening too many sessions concurrently. Note: in case that the SOAP request requires to read many node values simultaneously in one RPC operation such as GetParameterValues and GetParameterNames, there is risk that the consistency of data may not be kept because of value changes during the operation. Therefore, the protocol adapter is recommended to open the session as LOCK_TYPE_EXCLUSIVE for those RPCs, although these RPCs do not need to write any node value. Note: if the received RPC needs to write only one node value, the protocol adapter may use LOCK_TYPE_EXCLUSIVE because there is no reason to support transactions. If a data plugin does not support the TransactionalDataSession but does support the ReadWriteDataSession, the protocol adapter may use the LOCK_TYPE_EXCLUSIVE instead of the LOCK_TYPE_ATOMIC. In this case, the atomicity of the data is not ensured by the DMT Admin service. If a data plugin does not support either the TransactionalDataSession or ReadWriteDataSession, the protocol adapter can not change values for any nodes and should return the corresponding SOAP Fault response to the remote manager. The protocol adapter may open or close the session every time it receives a SOAP Request or sends the corresponding SOAP Response, respectively Commit for Atomic Session The DMT Admin supports the transaction management of the operations conducted through the DmtSession interface. However, there is no explicit RPC in the TR-069 specification to handle atomicity of those operations. Therefore, this RFC recommends the following implementation regarding the management of the transactional session. Let us assume that the protocol adapter receives the SOAP request from the remote manager and the protocol adapter needs to use a LOCK_TYPE_ATOMIC session as described in Section In that case, the session should be opened at the start of processing the request that needs to write node values, if the session has not been opened. If the corresponding RPC operation has been completed normally, the protocol adapter should call the DmtSession.commit() method before returning the SOAP response to the remote manager. After calling commit(), it can close the session. Note: even if the corresponding SOAP response fails to send to the remote manager, the changed data will be stored in the data plugin because the protocol adapter cannot rollback the operation after calling commit(). If the protocol adapter encounters any error conditions during the operation, such as DmtExceptions, it should call the DmtSession.rollback() to restore data consistency and should return SOAP Fault response to the remote manager. Fig.3 Sequence Examples of transaction management Copyright NTT Corporation 2010

401 RFC-149 TR-069 Protocol Implementation Guideline Page 18 of 32 Draft 9 October Mapping of data types There 9 data types are defined in the TR-106 [7], while extended Dmt Admin Service specification based on RFC141 defines more than 9 DmtData types. It means, there exists no obvious one-to-one mapping. Therefore the mapping rule is needed Mapping for GetParameterValues RPC For handling GetParameterValues RPC, the TR-069 Protocol Adapter can get DmtData of the corresponding node URI and the DmtData must have its format. This RFC defines mapping rule from the format to the TR-069 data type to be used in GetParameterValueResponse RPC as Table 3. Table 3:Mapping from the Format to TR-069 data type for GetParameterValues RPC Leaf or Interior Leaf FORMAT of the DmtData of the specified node FORMAT_BASE64 The datatype that TR069 XML in GetParameterValu esresponse needs to specify. base64 comment The byte array returned by DmtData.getBase64() will be converted into base64. The result of the conversion will be used as value. FORMAT_BINARY hexbinary DmtData.toString() will be used as value. FORMAT_BOOLEAN FORMAT_DATE FORMAT_FLOAT FORMAT_INTEGER FORMAT_NULL boolean string string int string 0 or 1, which DmtData.getBoolean() is translated into, will be used as value. DmtData.toString() will be used as value. FORMAT_RAW_BINARY base64 The byte array returned by DmtData#getRawBinary() will be converted into base64. The result of the conversion will be used as value. FORMAT_RAW_STRING string DmtData.toString() will be used as value. FORMAT_STRING string DmtData.toString() will be used as value. FORMAT_TIME string DmtData.toString() will be used as value. FORMAT_XML string DmtData.toString() will be used as value. FORMAT_UNSIGNED_IN TEGER unsignedint DmtData.toString() will be used as value. FORMAT_LONG long DmtData.toString() will be used as value. FORMAT_UNSIGNED_LO NG unsignedlong DmtData.toString() will be used as value. FORMAT_DATETIME datetime DmtData.toString() will be used as value. Copyright NTT Corporation 2010

402 RFC-149 TR-069 Protocol Implementation Guideline Page 19 of 32 Draft 9 October 2010 FORMAT_HEXBINARY hexbinary DmtData.toString() will be used as value. FORMAT_NODE_URI string Interior FORMAT_NODE string, or error. The returned String by DmtData.toString() will be translated into TR-069Path. For the translation, TR069URI.getTR069Path() can be used. The result of the translation will be used as value. If the type of the node is org.osgi/1.0/listsubtree, the subtree under the node should be treated as a list subtree. Otherwise, error. All DmtData objects of the child leaf nodes will be retrieved and values of each will be gotten as different rows in this table show. The values will be percent escaped and concatenated with each others into Comma-Separated String Mapping for SetParameterValues RPC Mapping for SetParameterValues RPC is more complicated than the one for GetParameterValues RPC, because one node in DMT can support multiple formats. The formats which a node supports can be retrieved by MetaNode.getFormats(). If the data type is any of boolean, int, unsignedint, long, unsignedlong and datetime, the mapping is simple as Table 4. If the corresponding node in DMT does not support the FORMAT specified in the table, setting ParematerValue for the node is failed. Table 4:Mapping from the TR-069 data type to Format for GetParameterValues RPC for boolean, int, unsignedint, long, unsignedlong, and datetime. The datatype that TR069 XML in SetParameterValues specified. FORMAT of the DmtData of the specified node to be used. comment boolean int unsignedint long unsignedlong FORMAT_BOOLEAN FORMAT_INTEGER FORMAT_UNSIGNED_I NTEGER FORMAT_LONG FORMAT_UNSIGNED_L ONG DmtData(boolean) is used according to the value 0 or 1. If the value is not either 0 or 1, setting ParematerValue for the node is failed. DmtData(int) will be used. If the parsing the value as int is failed, setting ParematerValue for the node is failed. DmtData(String, int format) will be used. If the constructor throws Exception, setting ParematerValue for the node is failed. DmtData(long) will be used. If the parsing the value as long is failed, setting ParematerValue for the node is failed. DmtData(String, int format) will be used. If the constructor throws Exception, setting ParematerValue for the node is failed. Copyright NTT Corporation 2010

403 RFC-149 TR-069 Protocol Implementation Guideline Page 20 of 32 Draft 9 October 2010 datetime FORMAT_DATETIME DmtData(String, int format) will be used. If the constructor throws Exception, setting ParematerValue for the node is failed. If the data type is any of binary, hexbinary, and string, the mapping is more complicated, because one node in DMT can support multiple formats. For example, in the case that the data type is string and the corresponding node can supports both of FORMAT_DATE and FORMAT_STRING, TR-069 Protocol Adapter needs to choose any of them. To keep consistent behavior of TR-069 Protocol Adapter, this RFC defines the following algorithms: Case1: TR-069 data type is base If the node supports FORMAT_BASE64, go to Step 1.a., otherwise, go to Step 2. a. The TR-069 Protocol Adapter chooses FORMAT_BASE64: it coverts the specified value to base64 byte array and constructs DmtData(byte[], boolean) with true as the second argument. 2. If the node supports FORMAT_RAW_BINARY, go to Step 2.a., otherwise, go to Step 3. a. The TR-069 Protocol Adapter gets array of raw format names by MetaNode.getRawFormatNames(). b. If the returned array has size zero or the first element of it is null or empty String, go to Step 3. Otherwise, the TR-069 Protocol Adapter chooses FORMAT_RAW_BINARY. It encodes the value String into a sequence of bytes using the character set specified in SOAP request. If the encoding fails, go to Step3. Otherwise, then it constructs DmtData(int, byte[]) with the first elements in the array of raw format names as the first argument. 3. setting ParematerValue for the node is failed. Case2: TR-069 data type is hexbinary. 1. If the node supports FORMAT_HEXBINARY, go to Step 1.a., otherwise, go to Step 2. a. The TR-069 Protocol Adapter chooses FORMAT_HEXBINARY: it coverts the specified value to hexbinary byte array and constructs DmtData(byte[], FORMAT_HEXBINARY). 2. If the node supports FORMAT_BINARY, go to Step 2.a., otherwise, go to Step 3. a. TR-069 Protocol Adapter choose FORMAT_BINARY. It encodes the value String into a sequence of bytes using the character set specified in SOAP request. If the encoding fails, go to Step3. Otherwise, then it constructs DmtData(byte[], FORMAT_BINARY). 3. setting ParematerValue for the node is failed. Case3: TR-069 data type is string. 1. If the node supports FORMAT_NULL, go to Step 1.a., otherwise, go to Step 2. a. if the value is empty String, then FORMAT_NULL is chosen. Otherwise go to Step 2. Copyright NTT Corporation 2010

404 RFC-149 TR-069 Protocol Implementation Guideline Page 21 of 32 Draft 9 October If the node supports FORMAT_FLOAT, go to Step 2.a., otherwise, go to Step 3. a. If the parsing as float succeeds, then FORMAT_FLOAT is chosen. Otherwise go to Step If the node supports FORMAT_DATE, go to Step 3.a., otherwise, go to Step 4. a. If the construct DmtData(String, FORMAT_DATE) succeeds, then FORMAT_DATE is chosen, Otherwise go to Step If the node supports FORMAT_TIME, go to Step 4.a., otherwise, go to Step 5. a. If the construct DmtData(String, FORMAT_TIME) succeeds, then FORMAT_TIME is chosen, Otherwise go to Step If the node supports FORMAT_NODE_URI, go to Step 5.a., otherwise, go to Step 6. a. If the construct DmtData(String, FORMAT_NODE_URI) succeeds, then FORMAT_NODE_URI is chosen, Otherwise go to Step 6. Before construct a DmtData object, TR-069 Protocol Adapter has to translate the value to absolute URI, if the value is relative path reference, which starts with./. 6. If the node supports FORMAT_RAW_STRING, go to Step 6.a., otherwise, go to Step 7. a. The TR-069 Protocol Adapter gets array of raw format names by MetaNode.getRawFormatNames(). b. If the returned array has size zero or the first element of it is null or empty String, go to Step 7. Otherwise, the TR-069 Protocol Adapter chooses FORMAT_RAW_STRING: it constructs DmtData(String, String). 7. If the node supports FORMAT_STRING, go to Step 7.a., otherwise, go to Step 8. a. The TR-069 Protocol Adapter chooses FORMAT_STRING: it constructs DmtData(String). 8. If the node supports FORMAT_XML, go to Step 8.a., otherwise, go to Step 9. a. The TR-069 Protocol Adapter chooses FORMAT_XML: it constructs DmtData(String, FORMAT_XML). 9. setting ParematerValue for the node is failed. 6.5 Error code and SOAP Fault Error code and Fault code mapping The DMT Admin specification defines The DmtIllegalStateException and the DmtException containing 17 codes to represent the cause of an error. On the other hand, TR-069 defines 20 fault codes as standard errors in its specification. Therefore, this RFC defines the mapping between these error codes and fault codes. Table 5:Mapping of Exception code to TR-069 Fault Code Class DmtException code TR-069 Fault code Remarks DmtException ALERT_NOT_ROUTED None This error never happens against a protocol adapter. COMMAND_FAILED 9002 COMMAND_NOT_ALLOWED 9003 For the CWMP fault element For the SetParameterValuesFault element. Copyright NTT Corporation 2010

405 RFC-149 TR-069 Protocol Implementation Guideline Page 22 of 32 Draft 9 October 2010 CONCURRENT_ACCESS 9003 For the CWMP fault element. DATA_STORE_FAILURE For the SetParameterValuesFault element. FEATURE_NOT_SUPPORTED 9003 Only for the CWMP fault due to the SetParameterValues RPC For the SetParameterValuesFault element Only for the CWMP fault due to the SetParameterAttributes RPC For the CWMP fault due to the other RPCs. INVALID_URI 9003 Only for the CWMP fault due to the SetParameterValues RPC For the SetParameterValuesFault element For the CWMP fault due to the other RPCs. METADATA_MISMATCH 9003 For the CWMP fault element. NODE_ALREADY_EXISTS For the SetParameterValuesFault element. NODE_NOT_FOUND 9003 Only for the CWMP fault due to the SetParameterValues RPC For the SetParameterValuesFault element For the CWMP fault due to the other RPCs. PERMISSION_DENIED 9003 Only for the CWMP fault due to the SetParameterValues RPC For the SetParameterValuesFault element For the CWMP fault due to the other RPCs. REMOTE_ERROR None This error never happens against a protocol adapter. ROLLBACK_FAILED 9002 SESSION_CREATION_TIMEOUT 9002 TRANSACTION_ERROR 9003 For the CWMP fault element. UNAUTHORIZED For the SetParameterValuesFault element. Copyright NTT Corporation 2010

406 RFC-149 TR-069 Protocol Implementation Guideline Page 23 of 32 Draft 9 October 2010 DmtIllegalStat eexception SecurityExcep tion Other Exceptions URI_TOO_LONG 9003 Only for the CWMP fault due to the SetParameterValues RPC. None 9002 None 9001 None For the SetParameterValuesFault element For the CWMP fault due to the other RPCs SOAP Fault expression In this section, the expression of the SOAP Fault response is defined based on the error code and fault code mapping. If the SOAP fault does not contain SetParameterValuesFault, the protocol adapter must set a code and a message contained in a DmtException instance to a FaultCode element and a FaultString element in the SOAP Fault response, respectively. The code in the DmtException must change the Fault code according to Table 5. Other information such as a path and causes included in the DmtException instance may be added to the FaultString element. If the SOAP fault is raised by the SetParameterValues and needs to include SetParameterValuesFault element, the protocol adapter must set path, code and message contained in a DmtException instance to ParameterName, FaultCode element and FaultString element in the SetParameterValuesFault element, respectively. The code in the DmtException must change the Fault code according to Table 5. If there are multiple paths in the DmtException, each path must be described as one SetParameterValuesFault element. Other information such as cause information included in the DmtException instance may be added to the FaultString element included in the SetParameterValuesFalt element. 7 Javadoc 7.1 org.osgi.util.tr069 Class TR069ParameterValue java.lang.object org.osgi.util.tr069.tr069parametervalue Copyright NTT Corporation 2010

407 RFC-149 TR-069 Protocol Implementation Guideline Page 24 of 32 Draft 9 October 2010 public class TR069ParameterValueextends java.lang.object Class which contains value and data type for TR-069, and static methods of utilities. Field Summary static java.lang.string TR069DATATYPE_BASE64 static java.lang.string TR069DATATYPE_BOOLEAN static java.lang.string TR069DATATYPE_DATETIME static java.lang.string TR069DATATYPE_HEXBINARY static java.lang.string TR069DATATYPE_INT static java.lang.string TR069DATATYPE_LONG static java.lang.string TR069DATATYPE_STRING static java.lang.string TR069DATATYPE_UNSIGNED_INT static java.lang.string TR069DATATYPE_UNSIGNED_LONG Constructor Summary TR069ParameterValue(java.lang.String value, java.lang.string type) Constructor of TR-069 Parameter Value. Method Summary static DmtData getdmtdata(java.lang.string value, java.lang.string tr069type, java.lang.string valuecharsetname, java.lang.string nodeuri, MetaNode metanode) Get DmtData to be used for DmtSession#setNodeValue() against a leaf node. static DmtData[] getdmtdatasforlist(java.lang.string value, java.lang.string tr069type, java.lang.string valuecharsetname, java.lang.string nodeuri, MetaNode metanode) Get DmtData array to be used for DmtSession#setNodeValue() against the child nodes of the specified node uri. static TR069ParameterValue gettr069parametervalue(dmtdata data) Copyright NTT Corporation 2010

408 RFC-149 TR-069 Protocol Implementation Guideline Page 25 of 32 Draft 9 October 2010 Get the TR069ParameterValue be used for GetParameterValuesResponse RPC static TR069ParameterValue gettr069parametervalueforlist(dmtdata[] datas) Get the TR069ParameterValue be used for GetParameterValuesResponse RPC java.lang.string gettype() java.lang.string getvalue() static void main(java.lang.string[] args) Methods inherited from class java.lang.object clone, equals, finalize, getclass, hashcode, notify, notifyall, tostring, wait, wait, wait Field Detail TR069DATATYPE_INT public static java.lang.string TR069DATATYPE_INT TR069DATATYPE_UNSIGNED_INT public static java.lang.string TR069DATATYPE_UNSIGNED_INT TR069DATATYPE_LONG public static java.lang.string TR069DATATYPE_LONG TR069DATATYPE_UNSIGNED_LONG public static java.lang.string TR069DATATYPE_UNSIGNED_LONG Copyright NTT Corporation 2010

409 RFC-149 TR-069 Protocol Implementation Guideline Page 26 of TR069DATATYPE_STRING Draft 9 October 2010 public static java.lang.string TR069DATATYPE_STRING TR069DATATYPE_BOOLEAN public static java.lang.string TR069DATATYPE_BOOLEAN TR069DATATYPE_BASE64 public static java.lang.string TR069DATATYPE_BASE TR069DATATYPE_HEXBINARY public static java.lang.string TR069DATATYPE_HEXBINARY TR069DATATYPE_DATETIME public static java.lang.string TR069DATATYPE_DATETIME Constructor Detail TR069ParameterValue public TR069ParameterValue(java.lang.String value, java.lang.string type) Constructor of TR-069 Parameter Value. Parameters: value - value to be used. tr069datatype - data type defined in TR-069. Method Detail Copyright NTT Corporation 2010

410 RFC-149 TR-069 Protocol Implementation Guideline Page 27 of getvalue Draft 9 October 2010 public java.lang.string getvalue() gettype public java.lang.string gettype() getdmtdata public static DmtData getdmtdata(java.lang.string value, java.lang.string tr069type, java.lang.string valuecharsetname, java.lang.string nodeuri, MetaNode metanode) throws TR069MappingException, java.lang.illegalargumentexception, java.io.unsupportedencodingexception Get DmtData to be used for DmtSession#setNodeValue() against a leaf node. Parameters: value - value to be set to the specified node uri. It must not be null. tr069type - TR069 data type specified by SetPamaremeterValues RPC. It must not be null or empty. valuecharsetname - character set to be used for the value. If null, a platform default character set will be used. The character set is used for getting byte array from the specified value. nodeuri - URI of the leaf node in DMT. It must be valid absolute DMT URI. metanode - Meta node of the specified node uri. It must not be null. Returns: DmtData to be used for DmtSession#setNodeValue(). Throws: TR069MappingException - if creating DmtData is failed for some reasons. java.io.unsupportedencodingexception - if the specified character set name is not supported. IllegalArgumetException - if value is null, if tr069type is either null or empty, if nodeuri is invalid absolute DMT URI, or if metanode is null. java.lang.illegalargumentexception getdmtdatasforlist public static DmtData[] getdmtdatasforlist(java.lang.string value, java.lang.string tr069type, Copyright NTT Corporation 2010

411 RFC-149 TR-069 Protocol Implementation Guideline Page 28 of 32 Draft 9 October 2010 java.lang.string valuecharsetname, java.lang.string nodeuri, MetaNode metanode) throws TR069MappingException, java.lang.illegalargumentexception, java.io.unsupportedencodingexception Get DmtData array to be used for DmtSession#setNodeValue() against the child nodes of the specified node uri. The node specified by the node uri must be interior node which has the node type of. Parameters: value - value to be set to the specified interior node. It must not be null. tr069type - TR069 data type specified by SetPamaremeterValues RPC. It must not be null or empty. valuecharsetname - character set to be used for the value. If null, a platform default character set will be used. The character set is used for getting byte array from the specified value. nodeuri - URI of the interior node in DMT. It must be valid absolute DMT URI. metanode - Meta node of the child leaf node of the specified node uri. It must not be null. Returns: array of DmtData to be used for DmtSession#setNodeValue() against the child nodes of the specified node uri. Throws: TR069MappingException - if creating DmtData is failed for some reasons. java.io.unsupportedencodingexception - if the specified character set name is not supported. IllegalArgumetException - if value is null, if tr069type is either null or empty, if nodeuri is invalid absolute DMT URI, or if metanode is null. java.lang.illegalargumentexception gettr069parametervalueforlist public static TR069ParameterValue gettr069parametervalueforlist(dmtdata[] datas) Get the TR069ParameterValue be used for GetParameterValuesResponse RPC Parameters: data - DmtData retrieved from DMT. Returns: TR069ParameterValue to be used for GetParameterValuesResponse RPC gettr069parametervalue public static TR069ParameterValue gettr069parametervalue(dmtdata data) Get the TR069ParameterValue be used for GetParameterValuesResponse RPC Copyright NTT Corporation 2010

412 RFC-149 TR-069 Protocol Implementation Guideline Page 29 of 32 Draft 9 October 2010 Parameters: data - DmtData retrieved from DMT. Returns: TR069ParameterValue to be used for GetParameterValuesResponse RPC. 7.2 org.osgi.util.tr069 Class TR069URI java.lang.object org.osgi.util.tr069.tr069uri public class TR069URIextends java.lang.object Utility class for translating between DMT URI and TR-069 Path. Method Summary static java.lang.string getdmturi(java.lang.string tr069path) Get the URI in DMT corresponding to the specified path in TR-069. static java.lang.string gettr069path(java.lang.string uri) Get the TR069 path corresponding to the specified URI in DMT. static boolean isvalidtr069path(java.lang.string tr069path) Validate whether the specified path is in the format of TR069 path. Methods inherited from class java.lang.object clone, equals, finalize, getclass, hashcode, notify, notifyall, tostring, wait, wait, wait Method Detail getdmturi public static final java.lang.string getdmturi(java.lang.string tr069path) Get the URI in DMT corresponding to the specified path in TR-069. The specified TR-069 path should be valid. This method will not validate it. Partial path Parameters: tr069path - TR-069 path Returns: URI in DMT, corresponding to the specified TR-069 path. Copyright NTT Corporation 2010

413 RFC-149 TR-069 Protocol Implementation Guideline Page 30 of gettr069path Draft 9 October 2010 public static final java.lang.string gettr069path(java.lang.string uri) Get the TR069 path corresponding to the specified URI in DMT. The specified URI should be valid absolute URI. This method will not validate it. Parameters: uri - URI in DMT. Returns: path in TR-069, corresponding to the specified URI isvalidtr069path public static final boolean isvalidtr069path(java.lang.string tr069path) Validate whether the specified path is in the format of TR069 path. Parameters: tr069path - Returns: true if the specified path is in the format of TR069 path. Otherwise, false. 8 Considered Alternatives 8.1 Future work for notification handling As described in Section 4.2.1, in order to realize TR-069 based notification especially regarding internal changes in OSGi, what Data Plugins and TR-069 protocol adapter, respectively, needs to do should be clarified. However, those are out of scope of this RFC, because the much further discussion will be required for the clarification. 8.2 Future work for forced inform parameters Some data model specified by BBF, such as TR-098, defines some nodes as forced inform parameters. The values of the nodes must be included in the ParameterList argument of every Inform message to the ACS. How to realize it in OSGi should be clarified. However, those are out of scope of this RFC, because the much further discussion will be required for the clarification. Copyright NTT Corporation 2010

414 RFC-149 TR-069 Protocol Implementation Guideline Page 31 of 32 9 Security Considerations Draft 9 October 2010 All security requirements follow the DMT Admin specification. 10Document Support 10.1 References [1]. Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, RFC2119, March [2]. Software Requirements & Specifications. Michael Jackson. ISBN [3]. OMA, Open Mobile Alliance. The mission of the Open Mobile Alliance is to facilitate global user adoption of mobile data services by specifying market driven mobile service enablers that ensure service interoperability across devices, geographies, service providers, operators, and networks, while allowing businesses to compete through innovation and differentiation. [4]. OMA Device Management specification v1.2. The goal of the Device Management Working Group is to specify protocols and mechanisms that achieve management of mobile devices including the necessary configuration to access services and management of the software on mobile devices. [5]. CPE WAN Management Protocol, TR-069 amendment 2, December [6]. The Broadband Forum is a global consortium of nearly 200 leading industry players covering telecommunications, equipment, computing, networking and service provider companies. Established in 1994, originally as the ADSL Forum and later the DSL Forum, the Broadband Forum continues its drive for a global mass market for broadband, to deliver the benefits of this technology to end users around the world over existing copper telephone wire infrastructures. [7]. Data model template for TR-069 enabled devices, TR-106 amendment 1, November 2006 Copyright NTT Corporation 2010

415 RFC-149 TR-069 Protocol Implementation Guideline Page 32 of Author's Address Draft 9 October 2010 Name Company Address Koya Mori NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice [email protected] Name Company Address Ikuo Yamasaki NTT Corporation Y320C, 1-1 Hikari-no-oka, Yokosuka, Kanagawa, Japan Voice [email protected] 10.3 Acronyms and Abbreviations 10.4 End of Document Copyright NTT Corporation 2010

416 The OSGi Alliance and its members specify, create, advance, and promote wide industry adoption of an open delivery and management platform for application services in home, commercial buildings, automotive and industrial environments. The OSGi Alliance serves as the focal point for a collaborative ecosystem of service providers, developers, manufacturers, and consumers. The OSGi specifications define a standardized, component oriented, computing environment for networked services. OSGi technology is currently being delivered in products and services shipping from several Fortune 100 companies. The OSGi Alliance s horizontal software integration platform is ideal for both vertical and cross-industry business models within home, vehicle, mobile and industrial environments. As an independent non-profit corporation, the OSGi Alliance also provides for the fair and uniform creation and distribution of relevant intellectual property including specifications, reference implementations, and test suites to all its members. HOW TO REACH US: OSGi Alliance Bishop Ranch Camino Ramon, Suite 375 San Ramon, CA USA Phone: [email protected] Web: OSGi is a trademark of the OSGi Alliance in the United States, other countries, or both. Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. All other marks are trademarks of their respective companies OSGi Alliance.

FME SOFTWARE LICENSE AGREEMENT

FME SOFTWARE LICENSE AGREEMENT FME SOFTWARE LICENSE AGREEMENT IMPORTANT READ CAREFULLY: This FME Software License Agreement ("Agreement") is a legal agreement between You (either an individual or a single legal entity) and Safe Software

More information

This is a legal agreement ("Agreement") between the undersigned (either an individual or an entity)

This is a legal agreement (Agreement) between the undersigned (either an individual or an entity) Royalty Free Web Services Security Specification License Agreement This is a legal agreement ("Agreement") between the undersigned (either an individual or an entity) ( Company ), and Microsoft Corporation

More information

RockWare Click-Wrap Software License Agreement ( License )

RockWare Click-Wrap Software License Agreement ( License ) RockWare, Inc. ( RockWare ) 2221 East Street, Suite 101 Golden CO 80401 USA RockWare Click-Wrap Software License Agreement ( License ) IMPORTANT - READ ALL OF THE TERMS AND CONDITIONS IN THIS LICENSE CAREFULLY

More information

CONTRIBUTION AGREEMENT VERSION 1.1

CONTRIBUTION AGREEMENT VERSION 1.1 CONTRIBUTION AGREEMENT VERSION 1.1 THIS CONTRIBUTION AGREEMENT (hereinafter referred to as Agreement ) is executed by you (either an individual or legal entity) ( Licensor ) in favor of Nokia Corporation,

More information

CITRIX SYSTEMS, INC. SOFTWARE LICENSE AGREEMENT

CITRIX SYSTEMS, INC. SOFTWARE LICENSE AGREEMENT CITRIX SYSTEMS, INC. SOFTWARE LICENSE AGREEMENT PLEASE READ THIS SOFTWARE LICENSE AGREEMENT CAREFULLY BEFORE DOWNLOADING, INSTALLING OR USING CITRIX OR CITRIX-SUPPLIED SOFTWARE. BY DOWNLOADING OR INSTALLING

More information

For Use of Source Code Developed By The Florida Department of Transportation

For Use of Source Code Developed By The Florida Department of Transportation STATE OF FLORIDA DEPARTMENT OF TRANSPORTATION SOFTWARE LICENSE AGREEMENT Other State Agencies Page 1 of 5 For Use of Source Code Developed By The Florida Department of Transportation Software License Agreement

More information

Mobile Banking Service Agreement (Addendum to your Primary Online Banking Service Agreement)

Mobile Banking Service Agreement (Addendum to your Primary Online Banking Service Agreement) Mobile Banking Service Agreement (Addendum to your Primary Online Banking Service Agreement) I. INTRODUCTION PARTIES AND DEFINITIONS This Mobile Banking Service Agreement (as amended from time to time,

More information

PLANTTOGETHER REFERRAL PARTNER AGREEMENT. Updated: January 1, 2015

PLANTTOGETHER REFERRAL PARTNER AGREEMENT. Updated: January 1, 2015 PLANTTOGETHER REFERRAL PARTNER AGREEMENT Updated: January 1, 2015 Welcome to PlanetTogether s online referral program (the Referral Program ) provided by PlanetTogether, Inc. a California corporation with

More information

WI-FI ALLIANCE INTELLECTUAL PROPERTY RIGHTS POLICY

WI-FI ALLIANCE INTELLECTUAL PROPERTY RIGHTS POLICY WI-FI ALLIANCE INTELLECTUAL PROPERTY RIGHTS POLICY BACKGROUND The purpose of the Wi-Fi Alliance ( WFA ) is to promote the IEEE 802.11 wireless networking standard by encouraging manufacturers of wireless

More information

BNSync User License Agreement

BNSync User License Agreement BNSync User License Agreement This Agreement ("Agreement") contains the complete terms and conditions that apply to your installation and use of BNSync, a proprietary software product that is owned and

More information

Ya-YaOnline Platform ( Service ).

Ya-YaOnline Platform ( Service ). SOFTWARE AS A SERVICE AGREEMENT FOR THE USE OF: Ya-YaOnline Platform ( Service ). NOW IT IS HEREBY AGREED by and between the parties hereto as follows:- Definitions "Agreement" means this Agreement and

More information

Equinox Framework: A Happier OSGi R6 Implementation

Equinox Framework: A Happier OSGi R6 Implementation Equinox Framework: A Happier OSGi R6 Implementation Tom Watson IBM March 18 th 2014 OSGi Alliance Marketing 2008-2010 Page. 1 All Rights Reserved Agenda New to OSGi R6 Core Redesign Core Equinox and Why

More information

INTEL SOFTWARE LICENSE AGREEMENT (OEM / IHV / ISV Distribution & Single User)

INTEL SOFTWARE LICENSE AGREEMENT (OEM / IHV / ISV Distribution & Single User) INTEL SOFTWARE LICENSE AGREEMENT (OEM / IHV / ISV Distribution & Single User) By clicking the Accept button, I signify that I have read and accept the terms below. IMPORTANT - READ BEFORE COPYING, INSTALLING

More information

End User License Agreement for the Intel(R) Software Development Products

End User License Agreement for the Intel(R) Software Development Products IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. Do not copy, install, or use the Materials provided under this license agreement ("Agreement"), until you have carefully read the following terms and

More information

SOFTWARE LICENSE AGREEMENT

SOFTWARE LICENSE AGREEMENT SOFTWARE LICENSE AGREEMENT This Software License Agreement (this Agreement ) is entered into as of the installation date of the software by and between Nanotron Technologies GmbH, a German corporation

More information

Services Agreement between Client and Provider

Services Agreement between Client and Provider Services Agreement between Client and Provider This Services Agreement is part of the Member Contract between Client and Provider, effective upon Client s award and Provider s acceptance of a Job on the

More information

Software License Agreement

Software License Agreement Software License Agreement GRANT OF LICENSE This Accusoft Corporation ("ACCUSOFT") Agreement ("LICENSE") grants YOU ("LICENSEE") a non-exclusive and non-transferable right to use the trial mode version

More information

PLEASE READ THIS AGREEMENT CAREFULLY. BY INSTALLING, DOWNLOADING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO THE TERMS OF THIS AGREEMENT.

PLEASE READ THIS AGREEMENT CAREFULLY. BY INSTALLING, DOWNLOADING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO THE TERMS OF THIS AGREEMENT. Access Governance Suite 6 Lifecycle Manager 6 Compliance Manager 6 Software License Agreement PLEASE READ THIS AGREEMENT CAREFULLY. BY INSTALLING, DOWNLOADING OR OTHERWISE USING THE SOFTWARE, YOU AGREE

More information

WE RECOMMEND THAT YOU PRINT OUT AND KEEP A COPY OF THIS AGREEMENT FOR YOUR FUTURE REFERENCE.

WE RECOMMEND THAT YOU PRINT OUT AND KEEP A COPY OF THIS AGREEMENT FOR YOUR FUTURE REFERENCE. RAPID CONNECT SERVICES(sm) and SPECIFICATION LICENSE AGREEMENT THIS RAPID CONNECT SERVICES AND SPECIFICATION LICENSE AGREEMENT IS BETWEEN FIRST DATA MERCHANT SERVICES CORPORATION ( FDMS ) FDMS AND YOU,

More information

Partners in Care Welch Allyn Connex Software Development Kit License Agreement

Partners in Care Welch Allyn Connex Software Development Kit License Agreement This Software Development Kit End User ( Agreement ) is between Welch Allyn, Inc. ( Welch Allyn ) and the Customer identified in the purchase order ( Customer or You ), and it governs the Software Development

More information

ALPHA TEST LICENSE AGREEMENT

ALPHA TEST LICENSE AGREEMENT ALPHA TEST LICENSE AGREEMENT IMPORTANT NOTICE! PLEASE READ THIS STATEMENT AND THE ALPHA TEST LICENSE AGREEMENT COMPLETELY BEFORE USING THIS ALPHA SOFTWARE. BY CLICKING ON THE BUTTON MARKED YES BELOW OR

More information

If a Client and a Freelancer enter an independent contractor relationship, then this Freelancer Agreement ( Freelancer Agreement ) will apply.

If a Client and a Freelancer enter an independent contractor relationship, then this Freelancer Agreement ( Freelancer Agreement ) will apply. Freelancer Agreement If a Client and a Freelancer enter an independent contractor relationship, then this Freelancer Agreement ( Freelancer Agreement ) will apply. This Agreement is effective as of March

More information

ADDENDUM ThomasNet Mirrored Site Program

ADDENDUM ThomasNet Mirrored Site Program ADDENDUM ThomasNet Mirrored Site Program This Addendum by the undersigned Client ( Client ) is incorporated into and made part of the agreement(s) by and between Client and Thomas Industrial Network, Inc.

More information

MTConnect Institute Public Comment and Evaluation License Agreement

MTConnect Institute Public Comment and Evaluation License Agreement MTConnect Institute Public Comment and Evaluation License Agreement Effective 6/10/2015 The Association for Manufacturing Technology, a non-profit organization ( AMT ), and the MTConnect Institute jointly

More information

If you do not wish to agree to these terms, please click DO NOT ACCEPT and obtain a refund of the purchase price as follows:

If you do not wish to agree to these terms, please click DO NOT ACCEPT and obtain a refund of the purchase price as follows: IMPORTANT: READ THIS AGREEMENT CAREFULLY. THIS IS A LEGAL AGREEMENT BETWEEN AVG TECHNOLOGIES CY, Ltd. ( AVG TECHNOLOGIES ) AND YOU (ACTING AS AN INDIVIDUAL OR, IF APPLICABLE, ON BEHALF OF THE INDIVIDUAL

More information

These TERMS AND CONDICTIONS (this Agreement ) are agreed to between InfluencersAtWork,

These TERMS AND CONDICTIONS (this Agreement ) are agreed to between InfluencersAtWork, TERMS AND CONDITIONS INFLUENCERS AT WORK These TERMS AND CONDICTIONS (this Agreement ) are agreed to between InfluencersAtWork, Ltd. ( InfluencerAtWork ) and you, or if you represent a company or other

More information

Crestron VMK-WIN TouchPoint Virtual Mouse & Keyboard Software for Windows Installation Guide

Crestron VMK-WIN TouchPoint Virtual Mouse & Keyboard Software for Windows Installation Guide Crestron VMK-WIN TouchPoint Virtual Mouse & Keyboard Software for Windows Installation Guide This document was prepared and written by the Technical Documentation department at: Crestron Electronics, Inc.

More information

USB 3.0 ADOPTERS AGREEMENT

USB 3.0 ADOPTERS AGREEMENT Notice: This agreement is not effective until a fully executed original has been received by the Secretary, Intel Corporation, at 2111 NE 25 th Avenue, Mailstop JF5-373, Hillsboro, OR 97124, Attn: Brad

More information

License and Maintenance Agreement

License and Maintenance Agreement License and Maintenance Agreement between you (either an individual person or a single legal entity, hereinafter Customer or You ) and Data Geekery GmbH, Zwinglistrasse 17, 8004 Zürich, Switzerland (hereinafter

More information

AGREEMENT AND TERMS OF USE

AGREEMENT AND TERMS OF USE AGREEMENT AND TERMS OF USE The website located at www.100womeninhedgefunds.org and the services of 100 Women in Hedge Funds ( 100WHF ) available thereon (collectively, the Site ), together with the networking

More information

ALL WEATHER, INC. SOFTWARE END USER LICENSE AGREEMENT

ALL WEATHER, INC. SOFTWARE END USER LICENSE AGREEMENT ALL WEATHER, INC. SOFTWARE END USER LICENSE AGREEMENT THIS SOFTWARE END USER LICENSE AGREEMENT (THIS AGREEMENT ) IS DATED FOR REFERENCE PURPOSES ONLY AS OF MARCH 26, 2009, AND IS BY AND BETWEEN ALL WEATHER,

More information

HYBRID SOLUTIONS INDEPENDENT SOFTWARE VENDOR AGREEMENT

HYBRID SOLUTIONS INDEPENDENT SOFTWARE VENDOR AGREEMENT HYBRID SOLUTIONS INDEPENDENT SOFTWARE VENDOR AGREEMENT THE VERTEXFX TRADER API (THE SOFTWARE ) AND THE ACCOMPANYING DOCUMENTATION (THE RELATED MATERIALS ) (COLLECTIVELY, THE PRODUCT ) ARE PROTECTED BY

More information

C-DAC Medical Informatics Software Development Kit End User License Agreement

C-DAC Medical Informatics Software Development Kit End User License Agreement C-DAC Medical Informatics Software Development Kit End User License Agreement BY DOWNLOADING AND INSTALLING, COPYING OR OTHERWISE USING THE CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING ( C-DAC ) MEDICAL

More information

APP SOFTWARE LICENSE AGREEMENT

APP SOFTWARE LICENSE AGREEMENT APP SOFTWARE LICENSE AGREEMENT This App Software License Agreement (the Agreement ) is made by and between AvePoint, Inc., a Delaware company, with offices at Harborside Financial Center, Plaza 10, 3 Second

More information

SUBSCRIPTION SERVICES.

SUBSCRIPTION SERVICES. SUSE Manager Server SUSE Manager Server with Database SUSE Software License Agreement PLEASE READ THIS AGREEMENT CAREFULLY. BY PURCHASING, INSTALLING AND/OR USING THE SOFTWARE (INCLUDING ITS COMPONENTS),

More information

SOFTWARE LICENSE AGREEMENT (Web Version October 18, 2002)

SOFTWARE LICENSE AGREEMENT (Web Version October 18, 2002) SOFTWARE LICENSE AGREEMENT (Web Version October 18, 2002) Whenever LICENSEE licenses software products ( Program(s) as further defined herein), a License Form shall be executed which shall refer to this

More information

Service Description: Cisco Prime Home Hosted Services. This document describes the Cisco Prime Home Hosted Services.

Service Description: Cisco Prime Home Hosted Services. This document describes the Cisco Prime Home Hosted Services. Service Description: Cisco Prime Home Hosted Services This document describes the Cisco Prime Home Hosted Services. Related Documents: The following documents also posted at www.cisco.com/go/servicedescriptions/

More information

Canon USA, Inc. WEBVIEW LIVESCOPE SOFTWARE DEVELOPMENT KIT DEVELOPER LICENSE AGREEMENT

Canon USA, Inc. WEBVIEW LIVESCOPE SOFTWARE DEVELOPMENT KIT DEVELOPER LICENSE AGREEMENT Canon USA, Inc. WEBVIEW LIVESCOPE SOFTWARE DEVELOPMENT KIT DEVELOPER LICENSE AGREEMENT This Webview Livescope Software Development Kit Developer License ("Agreement") between you, the "Developer" and the

More information

1.1 Authorized User means an employee of Customer who has been issued a User ID in accordance with Section 3.2(a).

1.1 Authorized User means an employee of Customer who has been issued a User ID in accordance with Section 3.2(a). RealPrence Cloud Video Meeting Services POLYCOM, INC., VIDEO-AS-A-SERVICE TERMS OF SERVICE This Video-as-a-Service Terms of Service (the Agreement ) govern the access to and use of the VaaS by each person

More information

Jozii LLC WEBSITE TERMS OF SERVICE

Jozii LLC WEBSITE TERMS OF SERVICE Jozii LLC WEBSITE TERMS OF SERVICE 1. Acceptance of Terms. Welcome to Jozii. By using our Internet website, you indicate your unconditional acceptance of the following Terms of Service. Please read them

More information

SPYDERS END USER LICENSE AGREEMENT TERMS AND CONDITIONS

SPYDERS END USER LICENSE AGREEMENT TERMS AND CONDITIONS SPYDERS END USER LICENSE AGREEMENT TERMS AND CONDITIONS 1. IMPORTANT NOTICE PLEASE READ THE TERMS AND CONDITIONS OF THIS LICENSE AGREEMENT (THE AGREEMENT ) CAREFULLY BEFORE PROCEEDING TO USE THE ENCLOSED

More information

ALM Works End-User License Agreement for Structure Plugin

ALM Works End-User License Agreement for Structure Plugin ALM Works End-User License Agreement for Structure Plugin IMPORTANT - READ CAREFULLY: This End-User License Agreement (EULA) is a legal agreement between you (either an individual or a single legal entity)

More information

terms of use Redis Labs Enterprise Cluster (RLEC) Subscription Agreement Last Updated: July 26, 2015

terms of use Redis Labs Enterprise Cluster (RLEC) Subscription Agreement Last Updated: July 26, 2015 terms of use Redis Labs Enterprise Cluster (RLEC) Subscription Agreement Last Updated: July 26, 2015 Welcome! Redis Labs, Inc., Redis Labs Ltd. and their affiliates ( Redis Labs, us, we or our ) provides

More information

Therm-App Software Development Kit License Agreement

Therm-App Software Development Kit License Agreement Therm-App Software Development Kit License Agreement 1. Introduction 1.1 Opgal is providing you with the Therm-App Software Development Kit intended for Android application developers (referred to in this

More information

Extension Module (XMOD): Batch Order Management (BOM)

Extension Module (XMOD): Batch Order Management (BOM) Extension Module (XMOD): Batch Order Management (BOM) 1999-Present Kryptronic, Inc. All rights reserved worldwide. Kryptronic, the Kryptronic logo and all Kryptronic software names and logos are trademarks

More information

SOLARWINDS, INC. ipmonitor 8.0 MANAGER END USER LICENSE AGREEMENT REDISTRIBUTION NOT PERMITTED

SOLARWINDS, INC. ipmonitor 8.0 MANAGER END USER LICENSE AGREEMENT REDISTRIBUTION NOT PERMITTED SOLARWINDS, INC ipmonitor 8.0 MANAGER END USER LICENSE AGREEMENT REDISTRIBUTION NOT PERMITTED IMPORTANT -- READ CAREFULLY BEFORE USING THIS SOFTWARE: THIS IS A LEGAL AGREEMENT BETWEEN YOU (EITHER AN INDIVIDUAL

More information

Extension Module (XMOD): SiteMap Generator

Extension Module (XMOD): SiteMap Generator Extension Module (XMOD): SiteMap Generator 1999-Present Kryptronic, Inc. All rights reserved worldwide. Kryptronic, the Kryptronic logo and all Kryptronic software names and logos are trademarks of Kryptronic,

More information

ENHANCED HOST CONTROLLER INTERFACE SPECIFICATION FOR UNIVERSAL SERIAL BUS (USB) 2.0 - ADOPTERS AGREEMENT

ENHANCED HOST CONTROLLER INTERFACE SPECIFICATION FOR UNIVERSAL SERIAL BUS (USB) 2.0 - ADOPTERS AGREEMENT ENHANCED HOST CONTROLLER INTERFACE SPECIFICATION FOR UNIVERSAL SERIAL BUS (USB) 2.0 - ADOPTERS AGREEMENT This Enhanced Host Controller Interface Specification for Universal Serial Bus (USB) 2.0 - Adopters

More information

MDM Zinc 3.0 End User License Agreement (EULA)

MDM Zinc 3.0 End User License Agreement (EULA) MDM Zinc 3.0 End User License Agreement (EULA) THIS AGREEMENT (or "EULA") IS A LEGAL AGREEMENT BETWEEN THE PERSON, COMPANY, OR ORGANIZATION THAT HAS LICENSED THIS SOFTWARE ("YOU" OR "CUSTOMER") AND MULTIDMEDIA

More information

Agreement. Whereas, ThinkGeek is interested in creating products based on the Idea.

Agreement. Whereas, ThinkGeek is interested in creating products based on the Idea. Agreement This Agreement is entered into as of ( Effective Date ) by and between ( Inventor ), [ADDRESS] and ThinkGeek, Inc., a Delaware corporation with an office at 11216 Waples Mill Rd., Suite 100,

More information

LICENSE AGREEMENT FOR TOBII ANALYTICS SOFTWARE DEVELOPMENT KIT AND API

LICENSE AGREEMENT FOR TOBII ANALYTICS SOFTWARE DEVELOPMENT KIT AND API LICENSE AGREEMENT FOR TOBII ANALYTICS SOFTWARE DEVELOPMENT KIT AND API PREAMBLE This Tobii Analytics Software Development Kit and API License Agreement (the "Agreement") forms a legally binding contract

More information

1. IMPORTANT NOTICE 2. LICENSE OF SOFTWARE PROGRAMS. 2.1. License Grant

1. IMPORTANT NOTICE 2. LICENSE OF SOFTWARE PROGRAMS. 2.1. License Grant RAPID FOCUS SECURITY, INC. DBA PWNIE EXPRESS END USER LICENSE AGREEMENT FOR ENTERPRISE PENTESTING APPLIANCE (EPA), PWN PLUG, PWN PLUG WIRELESS, PWN PLUG 3G, PWN PLUG ELITE, PWN PHONE, PWN PAD, PWN PLUG

More information

WEBSITE DEVELOPMENT STANDARD TERMS AND CONDITIONS

WEBSITE DEVELOPMENT STANDARD TERMS AND CONDITIONS WEBSITE DEVELOPMENT STANDARD TERMS AND CONDITIONS A. Client commitment: Client agrees to allocate time and process information, as needed, during the duration of the project. Client agrees to review the

More information

SourceKraft Systems & Consulting Ltd. LICENSE AGREEMENT FOR SOFTWARE APPLICATIONS

SourceKraft Systems & Consulting Ltd. LICENSE AGREEMENT FOR SOFTWARE APPLICATIONS SourceKraft Systems & Consulting Ltd. LICENSE AGREEMENT FOR SOFTWARE APPLICATIONS IMPORTANT READ CAREFULLY: This SourceKraft Systems & Consulting Ltd. ("SourceKraft") License Agreement ("License" or "Agreement")

More information

Oracle Binary Code License Agreement for the Java SE Platform Products and JavaFX

Oracle Binary Code License Agreement for the Java SE Platform Products and JavaFX Oracle Binary Code License Agreement for the Java SE Platform Products and JavaFX ORACLE AMERICA, INC. ("ORACLE"), FOR AND ON BEHALF OF ITSELF AND ITS SUBSIDIARIES AND AFFILIATES UNDER COMMON CONTROL,

More information

BROCADE COMMUNICATIONS SYSTEMS, INC. END USER SOFTWARE LICENSE AGREEMENT FOR BROCADE IP ANALYTICS PACK FOR VMWARE VREALIZE OPERATIONS

BROCADE COMMUNICATIONS SYSTEMS, INC. END USER SOFTWARE LICENSE AGREEMENT FOR BROCADE IP ANALYTICS PACK FOR VMWARE VREALIZE OPERATIONS BROCADE COMMUNICATIONS SYSTEMS, INC. END USER SOFTWARE LICENSE AGREEMENT FOR BROCADE IP ANALYTICS PACK FOR VMWARE VREALIZE OPERATIONS IMPORTANT: READ THIS CAREFULLY BEFORE INSTALLING, USING OR ELECTRONICALLY

More information

ZIMPERIUM, INC. END USER LICENSE TERMS

ZIMPERIUM, INC. END USER LICENSE TERMS ZIMPERIUM, INC. END USER LICENSE TERMS THIS DOCUMENT IS A LEGAL CONTRACT. PLEASE READ IT CAREFULLY. These End User License Terms ( Terms ) govern your access to and use of the zanti and zips client- side

More information

SOFTWARE AS A SERVICE AGREEMENT

SOFTWARE AS A SERVICE AGREEMENT SOFTWARE AS A SERVICE AGREEMENT YOU SHOULD READ CAREFULLY THE FOLLOWING TERMS AND CONDITIONS BEFORE UTILIZING THE SOFTWARE This is an agreement to remotely provide you with access to the functionality

More information

CO-MARKETING AGREEMENT

CO-MARKETING AGREEMENT CO-MARKETING AGREEMENT This CO-MARKETING AGREEMENT ( Agreement ) between [full legal name], a [entity type and state] ( Company1 ) and [full legal name], a Delaware corporation ( Company2 ) is effective

More information

NOTICE SOFTWARE END USER LICENSE AGREEMENT

NOTICE SOFTWARE END USER LICENSE AGREEMENT NOTICE SOFTWARE END USER LICENSE AGREEMENT THIS SOFTWARE END USER LICENSE AGREEMENT ( THIS AGREEMENT ) IS A LEGAL AND BINDING AGREEMENT BETWEEN YOU (EITHER AN INDIVIDUAL OR ENTITY) AND TP VISION NETHERLANDS

More information

Mayfair EULA for Journal Office

Mayfair EULA for Journal Office Mayfair EULA for Journal Office 9-April-2014 Page 1 of 9 Mayfair EULA for Journal Office Mayfair Software End User License Agreement Software programs which you received either installed on on the device

More information

Mobile Banking and Mobile Deposit Terms & Conditions

Mobile Banking and Mobile Deposit Terms & Conditions Mobile Banking and Mobile Deposit Terms & Conditions PLEASE CAREFULLY REVIEW THESE TERMS AND CONDITIONS BEFORE PROCEEDING: This Mobile Banking and Mobile Deposit Addendum ( Addendum ) to the Old National

More information

PointCentral Subscription Agreement v.9.2

PointCentral Subscription Agreement v.9.2 PointCentral Subscription Agreement v.9.2 READ THIS SUBSCRIPTION AGREEMENT ( AGREEMENT ) CAREFULLY BEFORE INSTALLING THIS SOFTWARE. THIS AGREEMENT, BETWEEN CALYX TECHNOLOGY, INC., DBA CALYX SOFTWARE (

More information

How To Use Etechglobal Online Store

How To Use Etechglobal Online Store 5204 S. Sand Cherry Circle, Sioux Falls SD 57108 www.etechglobal.com Phone: (605) 339-4529 Merchant Service and Licensing Agreement AGREEMENT The EtechGlobal Online Store service ("EtechGlobal Online Store"

More information

C. System Requirements. Apple Software is supported only on Apple-branded hardware that meets specified system requirements as indicated by Apple.

C. System Requirements. Apple Software is supported only on Apple-branded hardware that meets specified system requirements as indicated by Apple. ENGLISH APPLE INC. SOFTWARE LICENSE AGREEMENT FOR APPLE STORE APPLICATION PLEASE READ THIS SOFTWARE LICENSE AGREEMENT ("LICENSE") CAREFULLY BEFORE USING THE APPLE SOFTWARE. BY USING THE APPLE SOFTWARE,

More information

Table of Content. Introduction. Software Install and Uninstall. Software Features and GUI. Quick Getting Started Guide. Frequently Asked Questions

Table of Content. Introduction. Software Install and Uninstall. Software Features and GUI. Quick Getting Started Guide. Frequently Asked Questions Table of Content Introduction Overview System Requirements Software Install and Uninstall Install Uninstall Software Features and GUI Software Menu Options Software Navigation Quick Getting Started Guide

More information

ELECTRONIC ARTS SOFTWARE END USER LICENSE AGREEMENT

ELECTRONIC ARTS SOFTWARE END USER LICENSE AGREEMENT ELECTRONIC ARTS SOFTWARE END USER LICENSE AGREEMENT This End User License Agreement ( License ) is an agreement between you and Electronic Arts Inc., its subsidiaries and affiliates ( EA ). This License

More information

Microsoft Dynamics GP. Electronic Signatures

Microsoft Dynamics GP. Electronic Signatures Microsoft Dynamics GP Electronic Signatures Copyright Copyright 2006 Microsoft Corporation. All rights reserved. Complying with all applicable copyright laws is the responsibility of the user. Without

More information

Procon Frostbite 1.1 and subsequent releases End User License Agreement Revised: April 7, 2015

Procon Frostbite 1.1 and subsequent releases End User License Agreement Revised: April 7, 2015 Procon Frostbite 1.1 and subsequent releases End User License Agreement Revised: April 7, 2015 THIS IS A LEGAL AGREEMENT between "you", the individual, company, or organisation utilising Procon Frostbite

More information

HSS Specific Terms HSS SOFTWARE LICENSE AGREEMENT

HSS Specific Terms HSS SOFTWARE LICENSE AGREEMENT HSS Specific Terms HSS SOFTWARE LICENSE AGREEMENT 1. LICENSE 2. TERMINATION Subject to the terms and conditions of this HSS Software License Agreement (the Agreement ), HSS hereby grants to Client (herein

More information

Inject Design General Terms & Conditions

Inject Design General Terms & Conditions Inject Design General Terms & Conditions Latest Revision: April 2015 www.injectdesign.co.nz Content No. Contents Page No. 00 01 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 General Terms & Conditions

More information

OXFORD UNIVERSITY PRESS ONLINE JOURNALS: INSTITUTIONAL ONLINE AGREEMENT

OXFORD UNIVERSITY PRESS ONLINE JOURNALS: INSTITUTIONAL ONLINE AGREEMENT OXFORD UNIVERSITY PRESS ONLINE JOURNALS: INSTITUTIONAL ONLINE AGREEMENT IMPORTANT: BY COMPLETING THE ONLINE REGISTRATION MATERIALS, SIGNING AND SENDING THEM TO OXFORD UNIVERSITY PRESS (OR BY SELECTING

More information

SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT

SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT Note: By clicking I AGREE, downloading, installing, or using the SDK, you conclude and agree to the terms of this license agreement (the Agreement ) in a legally binding manner with AirWatch LLC., 1155

More information

END USER USER-SUBJECT-TO- QUALIFICATION SOFTWARE LICENSE AGREEMENT

END USER USER-SUBJECT-TO- QUALIFICATION SOFTWARE LICENSE AGREEMENT END USER USER-SUBJECT-TO- QUALIFICATION SOFTWARE LICENSE AGREEMENT For Access and Use of DRDPtech, software containing Desired Results Developmental Profiles 2010 (DRDP 2010) & DRDP (2015) 2014 Cloud Version

More information

ADP Ambassador /Referral Rewards Program. Terms and Conditions of Use

ADP Ambassador /Referral Rewards Program. Terms and Conditions of Use ADP Ambassador /Referral Rewards Program Terms and Conditions of Use These Terms and Conditions ("Terms") are an agreement between ADP, LLC ("ADP"), on behalf of its Major Accounts Services Division ("MAS"),

More information

Service Agreement: January 2008

Service Agreement: January 2008 International Consultants in Medicine Service Agreement: January 2008 Prior to enrolling in the service as a Member of any degree, you must agree to the following terms and conditions. You may accept these

More information

Statement of Work. for. Online Event Registration Product Deployment for Salesforce Implementation. for. Open Web Application Security Project (OWASP)

Statement of Work. for. Online Event Registration Product Deployment for Salesforce Implementation. for. Open Web Application Security Project (OWASP) Statement of Work for Online Event Registration Product Deployment for Salesforce Implementation for Open Web Application Security Project (OWASP) July 9, 2010 TABLE OF CONTENTS INTRODUCTION... 3 SCOPE...

More information

ACOT WEBSITE PRIVACY POLICY

ACOT WEBSITE PRIVACY POLICY ACOT WEBSITE PRIVACY POLICY Our commitment to privacy acot.ca (the Website ) is a website owned and operated by The Alberta College of Occupational Therapists ( ACOT ), also referred to as we, us, or our

More information

Specific Program Document ( License SPD )

Specific Program Document ( License SPD ) Specific Program Document ( License SPD ) 1. CA Europe s.a.r.l. ( CA ) licenses to Customer the CA software program(s) listed below under the following terms and conditions. By using the CA Software, Customer

More information

Sun Microsystems, Inc. ("Sun") ENTITLEMENT for SOFTWARE. Licensee/Company: Entity receiving Software.

Sun Microsystems, Inc. (Sun) ENTITLEMENT for SOFTWARE. Licensee/Company: Entity receiving Software. Sun Microsystems, Inc. ("Sun") ENTITLEMENT for SOFTWARE Licensee/Company: Entity receiving Software. Effective Date: Date of delivery of the Software to You. Software: JavaFX 1.2 Software Development Kit

More information

HTTP State Management

HTTP State Management HTTP State Management Candidate Version 1.1 27 Feb 2007 Open Mobile Alliance OMA-TS-HTTPSM-V1_1-20070227-C OMA-TS-HTTPSM-V1_1-20070227-C Page 2 (17) Use of this document is subject to all of the terms

More information

MICROSOFT COMMERCIAL TERMS OF USE FOR WINDOWS 10 IoT CORE RUNTIME IMAGE

MICROSOFT COMMERCIAL TERMS OF USE FOR WINDOWS 10 IoT CORE RUNTIME IMAGE MICROSOFT COMMERCIAL TERMS OF USE FOR WINDOWS 10 IoT CORE RUNTIME IMAGE This is an agreement between Microsoft Corporation or based on where you live, one of its affiliates Microsoft and You Agreement.

More information

TERMS OF USE & SERVICE

TERMS OF USE & SERVICE TERMS OF USE & SERVICE We request that you read these Terms of Use carefully. IMPORTANT! THESE TERMS OF SERVICE (TOS) GOVERN YOUR USE OF THIS SITE, WHICH IS PROVIDED BY OUR COMPANY. BY ACCESSING THIS SITE,

More information

Terms of Service. Your Information and Privacy

Terms of Service. Your Information and Privacy These terms of service (the "Terms") govern your access to and use of the Online File Storage ("OFS") websites and services (the "Service"). The Terms are between DigitalMailer, Incorporated and Digital

More information

Licence Agreement. Document filename. HSCIC Licence Agreement. Directorate / Programme. Solution, Design, Assurance and Standards. Status.

Licence Agreement. Document filename. HSCIC Licence Agreement. Directorate / Programme. Solution, Design, Assurance and Standards. Status. Document filename HSCIC Licence Agreement Directorate / Programme Solution, Design, Assurance and Standards Status Approved Version 1.0 Version issue date 01/04/2013 Licence Agreement INTRODUCTION This

More information

Software Usage Agreement

Software Usage Agreement Software Usage Agreement This agreement, dated, is between State of Minnesota, acting through its State Court Administrator s Office, Conservator Account Auditing Program, address 7533 Sunwood Drive NW,

More information

TERMS AND CONDITIONS

TERMS AND CONDITIONS TERMS AND CONDITIONS ACCEPTANCE OF ANY PURCHASE ORDER FROM A CUSTOMER FOR USE OF ANY EQUIPMENT AND SOFTWARE PROVIDED BY RX MONITORING SYSTEMS INC. ( RXMS ) IS CONDITIONED UPON THESE TERMS AND CONDITIONS.

More information

VIRTUAL OFFICE WEBSITE LICENSE AGREEMENT

VIRTUAL OFFICE WEBSITE LICENSE AGREEMENT Florida Keys Multiple Listing Service, Inc. VIRTUAL OFFICE WEBSITE LICENSE AGREEMENT Florida Keys MLS, Inc. 92410 Overseas Hwy, Ste. 11 Tavernier FL 33070 305-852-92940 305-852-0716 (fax) www.flexmls.com

More information

Adaptive System of School Improvement Support Tools (ASSIST ) TERMS AND CONDITIONS

Adaptive System of School Improvement Support Tools (ASSIST ) TERMS AND CONDITIONS Adaptive System of School Improvement Support Tools (ASSIST ) TERMS AND CONDITIONS Effective as of October 1, 2014 IMPORTANT THIS IS A LEGAL AGREEMENT BETWEEN YOU ("You" or the "Authorized User") AND ADVANCE

More information

Overview Software Assurance is an annual subscription that includes: Technical Support, Maintenance and Software Upgrades.

Overview Software Assurance is an annual subscription that includes: Technical Support, Maintenance and Software Upgrades. Software Maintenance & Support Agreement This agreement ( Support Agreement, Software Assurance, Agreement ) is for the purpose of defining the terms and conditions under which Technical Support, Maintenance

More information

Pervasive Software Inc. Pervasive PSQL v11 Insurance License Agreement

Pervasive Software Inc. Pervasive PSQL v11 Insurance License Agreement Pervasive Software Inc. Pervasive PSQL v11 Insurance License Agreement IMPORTANT: DO NOT INSTALL THE ENCLOSED OR DOWNLOADED SOFTWARE UNTIL YOU HAVE READ THIS PERVASIVE PSQL LICENSE AGREEMENT ( AGREEMENT

More information

Copyright 2006. Sagicor Life Insurance Company. All rights reserved.

Copyright 2006. Sagicor Life Insurance Company. All rights reserved. Terms & Conditions Welcome to Sagicor Life Insurance Company ( Sagicor ). Sagicor maintains this website for your personal information, education and communication. Your access to and use of this website

More information

SERVICE TERMS AND CONDITIONS

SERVICE TERMS AND CONDITIONS SERVICE TERMS AND CONDITIONS Last Updated: April 19th, 2016 These Service Terms and Conditions ( Terms ) are a legal agreement between you ( Customer or you ) and Planday, Inc., a Delaware corporation

More information

TERMS & CONDITIONS: LIMITED LICENSE:

TERMS & CONDITIONS: LIMITED LICENSE: TERMS & CONDITIONS: The use of any product, service or feature (the "Materials") available through the internet websites accessible at 4tellus.com, ("Website") by any user of the Website ("You" or "Your"

More information