rhino extended apis...rhino extended apis (v2.5.0) 3.2.3 datatype codecs.....31

120
Rhino Extended APIs TAS-006-Issue 2.5.0-Release 1 September 2018

Upload: others

Post on 26-Jul-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs

TAS-006-Issue 2.5.0-Release 1

September 2018

Page 2: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Notices

Copyright © 2017 Metaswitch Networks. All rights reserved.

This manual is issued on a controlled basis to a specific person on the understanding that no part of the Metaswitch Networks product code or

documentation (including this manual) will be copied or distributed without prior agreement in writing from Metaswitch Networks.

Metaswitch Networks reserves the right to, without notice, modify or revise all or part of this document and/or change product features or

specifications and shall not be responsible for any loss, cost, or damage, including consequential damage, caused by reliance on these materials.

Metaswitch and the Metaswitch logo are trademarks of Metaswitch Networks. Other brands and products referenced herein are the trademarks or

registered trademarks of their respective holders.

2

Page 3: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Contents

1 Rhino Extended APIs...................................................................................................................................................... 10

1.1 Topics......................................................................................................................................................................................................... 10

2 Bindings........................................................................................................................................................................... 11

2.1 Dynamic component reference bindings.................................................................................................................................................... 11

2.2 Install levels................................................................................................................................................................................................ 12

2.3 Component copy.........................................................................................................................................................................................16

2.4 Dynamic dependency specification............................................................................................................................................................ 18

2.4.1 Binding descriptor format.............................................................................................................................................................. 18

2.4.2 Managing binding descriptors....................................................................................................................................................... 19

2.4.3 Binding descriptor application....................................................................................................................................................... 20

2.4.4 Service binding capabilities...........................................................................................................................................................21

2.4.5 Binding conflicts............................................................................................................................................................................ 22

2.4.6 Associating a binding with a service............................................................................................................................................. 22

3 CMP Field Enhancements...............................................................................................................................................25

3.1 Array support.............................................................................................................................................................................................. 25

3.2 Serialization enhancements........................................................................................................................................................................25

3.2.1 FastSerializable............................................................................................................................................................................ 26

FastSerialize............................................................................................................................................................................... 27

Example...................................................................................................................................................................................... 27

3.2.2 Encodable..................................................................................................................................................................................... 28

EncoderUtils / DecoderUtils........................................................................................................................................................ 29

Example...................................................................................................................................................................................... 30

3

Page 4: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

3.2.3 Datatype codecs........................................................................................................................................................................... 31

Examples.................................................................................................................................................................................... 32

3.2.4 Encodable context........................................................................................................................................................................ 34

Encodable context definition....................................................................................................................................................... 34

Encodable context provider.........................................................................................................................................................35

3.2.5 Codecs for Java collection types.................................................................................................................................................. 37

Encodable collections................................................................................................................................................................. 37

Datatype codecs for collections.................................................................................................................................................. 40

3.2.6 Predefined datatype codecs......................................................................................................................................................... 41

3.3 Initial values................................................................................................................................................................................................ 42

3.3.1 Initial value fields...........................................................................................................................................................................42

Examples.................................................................................................................................................................................... 43

3.4 Pass-by-reference...................................................................................................................................................................................... 44

3.4.1 Reference scopes......................................................................................................................................................................... 44

Declaration.................................................................................................................................................................................. 45

Additional considerations............................................................................................................................................................ 46

3.5 CMP extension interfaces...........................................................................................................................................................................47

3.6 Arbitrary CMP fields....................................................................................................................................................................................50

3.7 The CMPFields interface............................................................................................................................................................................ 51

3.7.1 CMPFields object..........................................................................................................................................................................54

4 Miscellaneous SLEE Application API Enhancements..................................................................................................55

4.1 SbbContext interface extensions................................................................................................................................................................ 55

4.1.1 RhinoSbbContext interface getConvergenceName method......................................................................................................... 56

4.1.2 RhinoSbbContext interface getTracer method..............................................................................................................................56

4.1.3 RhinoSbbContext interface getActivities methods........................................................................................................................ 57

4

Page 5: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

4.1.4 RhinoSbbContext interface getChildRelationFacility method....................................................................................................... 57

4.1.5 RhinoSbbContext interface getCMPFields method...................................................................................................................... 57

4.1.6 RhinoSbbContext interface getJndiBindings method....................................................................................................................57

4.1.7 RhinoSbbContext interface setServiceContext and getServiceContext methods.........................................................................58

4.1.8 RhinoSbbContext interface setEncodableContext method...........................................................................................................58

4.2 Activity context Suspend/Resume Delivery extensions.............................................................................................................................. 59

4.2.1 RhinoActivityContextInterface interface suspendDelivery methods..............................................................................................60

4.2.2 RhinoActivityContextInterface interface resumeDelivery methods............................................................................................... 61

4.2.3 RhinoActivityContextInterface interface isSuspended methods................................................................................................... 62

4.2.4 Relationship to event context suspend/resume............................................................................................................................ 62

4.3 SBB local home interface........................................................................................................................................................................... 63

4.3.1 How to get an SBB local home object...........................................................................................................................................63

4.3.2 The RhinoSbbLocalHome interface.............................................................................................................................................. 63

4.3.3 SBB service lifecycle callbacks.....................................................................................................................................................64

4.3.4 RhinoSbbLocalHome interface verifyConfiguration method......................................................................................................... 64

4.3.5 RhinoSbbLocalHome interface serviceActivating method............................................................................................................ 65

4.3.6 RhinoSbbLocalHome interface serviceDeactivating method........................................................................................................ 66

4.3.7 Lifecycle callback method invocation cascade............................................................................................................................. 66

4.4 Unchecked throwable propagation............................................................................................................................................................. 67

5 SBB Parts......................................................................................................................................................................... 68

5.1 What are SBB parts?.................................................................................................................................................................................. 68

5.2 SBB part components.................................................................................................................................................................................68

5.3 SBBs and SBB parts...................................................................................................................................................................................69

5.4 SBB part objects......................................................................................................................................................................................... 70

5.4.1 SBB part object lifecycle............................................................................................................................................................... 71

5

Page 6: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

5.5 SBB part class............................................................................................................................................................................................ 73

5.5.1 Lifecycle methods......................................................................................................................................................................... 73

Constructor..................................................................................................................................................................................74

@PreDispose.............................................................................................................................................................................. 74

@PostCreate...............................................................................................................................................................................75

@OnActivate............................................................................................................................................................................... 76

@OnPassivate............................................................................................................................................................................ 76

@PreRemove..............................................................................................................................................................................77

@PostLoad................................................................................................................................................................................. 78

@PreStore.................................................................................................................................................................................. 78

5.5.2 Event handler methods................................................................................................................................................................. 79

5.5.3 Initial event selector methods....................................................................................................................................................... 80

5.5.4 Exception callback method........................................................................................................................................................... 81

RuntimeException handling for transactional methods............................................................................................................... 82

RuntimeException handling for non-transactional methods........................................................................................................82

5.5.5 Transaction rollback processing................................................................................................................................................... 83

5.5.6 Method name restrictions..............................................................................................................................................................83

5.5.7 Dependency injection....................................................................................................................................................................83

5.5.8 SBB abstract class abstract method replacements...................................................................................................................... 84

Per-instance state....................................................................................................................................................................... 84

Activity context interface narrow method.................................................................................................................................... 85

Child relations............................................................................................................................................................................. 85

Profile CMP interface accessor method......................................................................................................................................85

Usage parameters interface accessor methods..........................................................................................................................85

Fire event methods..................................................................................................................................................................... 86

6

Page 7: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

5.6 SbbPartContext interface............................................................................................................................................................................86

5.6.1 Methods inherited from SbbContext............................................................................................................................................. 86

5.6.2 SbbPartContext interface getSbbPart method..............................................................................................................................86

5.6.3 SbbPartContext interface getTracer method................................................................................................................................ 86

5.6.4 SbbPartContext interface asSbbPartActivityContextInterface method......................................................................................... 87

5.6.5 SbbPartContext interface getActivities methods...........................................................................................................................87

5.6.6 SbbPartContext interface getConvergenceName method............................................................................................................88

5.6.7 SbbPartContext interface getCMPFields method......................................................................................................................... 88

5.6.8 SbbPartContext interface getJndiBindings method...................................................................................................................... 88

5.7 SBB part component environment..............................................................................................................................................................88

5.8 SBB part example.......................................................................................................................................................................................88

6 SLEE Facilities................................................................................................................................................................. 90

6.1 SBB child relations......................................................................................................................................................................................90

6.1.1 Extended child relation declarations............................................................................................................................................. 90

6.1.2 Child Relation Facility................................................................................................................................................................... 91

ChildRelationFacility interface.....................................................................................................................................................91

6.1.3 ChildRelationFacility interface getChildRelationNames method...................................................................................................92

6.1.4 ChildRelationFacility interface getChildRelation method.............................................................................................................. 93

6.1.5 ChildRelationFacility interface getChildSbbs methods................................................................................................................. 93

6.1.6 ChildRelationFacility interface getChildSbbLocalHome method...................................................................................................93

6.2 Usage extensions....................................................................................................................................................................................... 94

6.2.1 Usage parameter types.................................................................................................................................................................94

6.2.2 Usage parameter sets...................................................................................................................................................................94

6.3 Usage parameter set types.........................................................................................................................................................................95

6.4 Aggregation and extension......................................................................................................................................................................... 95

7

Page 8: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.5 Usage parameters interfaces......................................................................................................................................................................96

6.6 Counter-type usage parameter set method................................................................................................................................................ 97

6.7 UsageParametersInterface interface.......................................................................................................................................................... 98

6.7.1 UsageParametersInterface interface name method..................................................................................................................... 99

6.7.2 UsageParametersInterface interface type method....................................................................................................................... 99

6.7.3 UsageParametersInterface interface key method.........................................................................................................................99

6.7.4 UsageParametersInterface interface getOrCreateChild methods................................................................................................ 99

6.7.5 UsageParametersInterface interface hasChild method................................................................................................................ 99

6.7.6 UsageParametersInterface interface children method................................................................................................................100

6.7.7 UsageParametersInterface interface parent method.................................................................................................................. 100

6.7.8 UsageParametersInterface interface remove method................................................................................................................ 100

6.8 Annotations...............................................................................................................................................................................................100

6.8.1 @UsageParameters annotation..................................................................................................................................................100

6.8.2 @UsageCounter annotation....................................................................................................................................................... 101

6.8.3 @UsageSample annotation........................................................................................................................................................ 102

6.9 SBB usage parameters interface deployment descriptor......................................................................................................................... 103

6.10 Resource adaptor usage parameters interface deployment descriptor.................................................................................................. 105

6.11 Usage facility.......................................................................................................................................................................................... 106

6.11.1 UsageFacility interface..............................................................................................................................................................106

6.11.2 UsageFacility interface getRootUsageParameterSet method.................................................................................................. 108

6.11.3 UsageFacility interface getUsageParameterSet method.......................................................................................................... 108

6.11.4 UsageFacility interface getOrCreateChild methods..................................................................................................................108

6.11.5 UsageFacility interface hasChild method..................................................................................................................................109

6.11.6 UsageFacility interface getChildren method............................................................................................................................. 109

6.11.7 UsageFacility interface removeUsageParameterSet method................................................................................................... 109

8

Page 9: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.12 Profile facility extensions........................................................................................................................................................................ 109

6.12.1 ProfileFacility interface..............................................................................................................................................................110

6.12.2 ProfileFacility interface profileTableExists method................................................................................................................... 110

6.12.3 ProfileFacility interface getProfileTableDescriptor method....................................................................................................... 110

6.12.4 ProfileFacility interface ProfileTableDescriptor interface.......................................................................................................... 111

6.12.5 ProfileFacility interface getProfileSpecification method............................................................................................................ 111

6.12.6 ProfileFacility interface getProfileTableInterface method..........................................................................................................111

6.12.7 ProfileFacility interface getProfileLocalInterface method.......................................................................................................... 112

6.13 Tracer extensions................................................................................................................................................................................... 112

6.13.1 Tracer interface.........................................................................................................................................................................112

6.13.2 Tracer interface getParentTracer method.................................................................................................................................112

6.13.3 Tracer interface getChildTracer method................................................................................................................................... 113

6.14 Lock Facility............................................................................................................................................................................................ 113

6.15 JNDI environment metadata................................................................................................................................................................... 115

6.15.1 JndiBinding class...................................................................................................................................................................... 116

6.15.2 JndiBinding class getType method........................................................................................................................................... 117

6.15.3 JndiBindingclass getJndiName method.................................................................................................................................... 117

6.15.4 JndiBindingclass getValue method........................................................................................................................................... 117

6.15.5 Subclasses of JndiBinding........................................................................................................................................................ 118

6.15.6 EnvEntry class.......................................................................................................................................................................... 118

6.15.7 Facility class..............................................................................................................................................................................118

6.15.8 LimiterEndpoint class................................................................................................................................................................118

6.15.9 ResourceAdaptorTypeBinding class.........................................................................................................................................119

6.15.10 ActivityContextInterfaceFactoryBinding class......................................................................................................................... 119

6.15.11 ResourceAdaptorEntityBinding class......................................................................................................................................120

9

Page 10: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

1 Rhino Extended APIs

This document provides API-level details for developers to extend SLEE services and OpenCloud Sentinel features.

Introduced in Rhino 2.4.0

1.1 Topics

Bindings

CMP Field Enhancements

Miscellaneous SLEE Application API Enhancements

SBB Parts

SLEE Facilities

Other documentation for the Rhino TAS can be found on the Rhino TAS product page .

10

Page 11: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

2 Bindings

Rhino has a dynamic approach on page 11 to dependency specification and binding, supported by multiple install levels on page 12 for

components, virtual copy on page 16 of installed components, and dependency specification on page 18 and application.

2.1 Dynamic component reference bindings

The JAIN SLEE specification states that every deployable component has an identity specified by a name, vendor, and version tuple. This identity

must be unique within the scope of a given component type. A component may reference other components of various types by specifying their

type and identity in the component deployment descriptor.

These references are static, that is: they are defined prior to installation in the SLEE; and once the component is installed the references cannot

be changed. Static references in general function adequately; however they can make the application upgrade process more complicated that it

need be.

For example, if a library component used by an application has a bug fixed and a new version of the library is produced, then all dependent

components such as SBBs and profile specifications need to have their references updated and new versions released; and all components

dependent on those, such as other SBBs and service components, also need updating and releasing; and so on through the chain of

dependencies.

A more dynamic approach to dependency specification and binding would help make the upgrade process easier. Rhino provides such an

approach, which is supported by the following concepts:

• multiple install levels on page 12 for components

• virtual copy on page 16 of installed components

• dependency specification on page 18 and application.

Each of these concepts is described in detail below.

11

Page 12: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

2.2 Install levels

The JAIN SLEE specification defines that a deployable unit and the components it contains is either installed or not installed in the SLEE. When

a deployable unit is installed, its components are verified for correctness, and if verification is successful the components are made ready for use;

for example, service components are initialised ready for activation.

To facilitate the management of dynamic component bindings, Rhino provides finer-grained control over the degree to which a deployable unit and

its components are installed. Installed components each have one of the following install levels :

• INSTALLED — The component is installed in the SLEE. The deployment descriptor has been validated for syntax and and has been

parsed; however any component and class references, configuration parameters, and other relevant information contained in the

deployment descriptor has not been verified for correctness.

• VERIFIED — The component is installed and has successfully passed all verification checks.

• DEPLOYED — The component is installed, it has passed verification, any necessary implementation code has been generated, and it

has been deployed to each cluster node ready for immediate use (such as service activation).

Here are some ways you can manage install levels:

Specify the level The initial install level for a deployable unit and the components it contains can be specified when the deployable

unit is installed. For example, using rhino-console :

[Rhino@localhost:2199 (#0)] installlocaldu /path/to/deployable-unit.jar -installlevel INSTALLED Installed: DeployableUnitID[url=file:/path/to/deployable-unit.jar]

The -installlevel parameter is optional. If an install level is not specified when a deployable unit isinstalled, an install level of DEPLOYED is assumed.

Verify an installed

component

An installed component can subsequently be verified using the verify management operation. For example,

using rhino-console :

12

Page 13: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

[Rhino@localhost:2199 (#0)] verify sbb name=MySBB,vendor=OpenCloud,version=1.0 SbbID[name=MySBB,vendor=OpenCloud,version=1.0] verified The following components were also verified: ProfileSpecificationID[name=MyProfileSpec,vendor=OpenCloud,version=1.0] LibraryID[name=MyLibrary,vendor=OpenCloud,version=1.0]

If the component being verified depends on other components that are installed but yet to be verified, then Rhino

will automatically verify those dependent components first. ( See the note about install levels on page

below. )

Verify an installed DU An installed deployable unit may also be "verified". Deployable unit verification is a convenience mechanism to

verify all the components contained in the deployable unit with a single command. For example, using rhino-

console :

[Rhino@localhost:2199 (#0)] verify du file:/path/to/deployable-unit.jar Deployable unit file:/path/to/deployable-unit.jar verified The following components were verified: SbbID[name=MySBB,vendor=OpenCloud,version=1.0] ProfileSpecificationID[name=MyProfileSpec,vendor=OpenCloud,version=1.0] LibraryID[name=MyLibrary,vendor=OpenCloud,version=1.0]

Only the deployable unit components that have yet to be verified are affected by this command. As such, verifying

a deployable unit that only contains already verified components has no further effect.

Deploy a component A component can be deployed using the deploy management operation. For example, using rhino-console :

[Rhino@localhost:2199 (#0)] deploy sbb name=MySBB,vendor=OpenCloud,version=1.0 SbbID[name=MySBB,vendor=OpenCloud,version=1.0] deployed No other components were affected by this operation

If the component being deployed depends on other components that are not yet deployed, then Rhino will

automatically deploy those dependent components first, and so on recursively. ( See the note about install levels

on page below. )

If any component being deployed has not yet been verified, then Rhino will automatically verify the component

before deploying it. The deploy operation will fail if any verification errors are found in this case.

13

Page 14: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Deploy an installed DU An installed deployable unit may also be "deployed". Deployable unit deployment is, again, a convenience

mechanism to deploy all the components contained in the deployable unit with a single command. A deployable

unit can be deployed in rhino-console , for example, as follows:

[Rhino@localhost:2199 (#0)] deploy du file:/path/to/deployable-unit.jar Deployable unit file:/path/to/deployable-unit.jar deployed The following components were deployed: SbbID[name=MySBB,vendor=OpenCloud,version=1.0] deployed

Only the deployable unit components that have yet to be deployed are affected by this command. As such,

deploying a deployable unit that only contains already deployed components has no further effect.

Undeploy a deployed

component

A deployed component can subsequently be undeployed. When a component is undeployed it reverts to the

VERIFIED install level. Dynamic changes to a component’s bindings cannot be made while a component is

DEPLOYED ; therefore it is necessary to undeploy a component if it is currently deployed and its bindings need to

be changed.

A deployed component is undeployed using the undeploy management operation. For example, using rhino-

console :

[Rhino@localhost:2199 (#0)] undeploy service name=MyService,vendor=OpenCloud,version=1.0 ServiceID[name=MyService,vendor=OpenCloud,version=1.0] undeployed No other components were affected by this operation

If there are any components that depend on the component being undeployed that themselves have an install level

of DEPLOYED , then those components too will also be undeployed by this operation, and so on recursively. ( See

the note about install levels on page below. )

An undeploy operation will fail if any component that would be affected by the operation does not satisfy the below

requirements:

• A service component can only be undeployed if it is in the INACTIVE state.

• A profile specification component can only be undeployed if there are no profile tables created from it

currently in existence.

14

Page 15: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• A resource adaptor component can only be undeployed if there are no resource adaptor entities

created from it currently in existence.

Unverify a component A verified or deployed component can subsequently be unverified. When a component is unverified it reverts

to the INSTALLED install level. If the component was deployed then it is undeployed first. Dynamic changes

to a component’s bindings cannot be made while a component install level is not INSTALLED . Rhino will

automatically unverify (but not undeploy) a verified component affected by a binding operation; however the

unverify management operation exists to allow this transition to be manually controlled. Manually unverifying a

component is also necessary if, for example, dependent linked or shadowed components need to be updated.

A component is unverified using the unverify management operation. For example, using rhino-console :

[Rhino@localhost:2199 (#0)] unverify service name=MyService,vendor=OpenCloud,version=1.0 ServiceID[name=MyService,vendor=OpenCloud,version=1.0] unverified No other components were affected by this operation

If there are any components that depend on the component being unverified that themselves have an install

level of VERIFIED or DEPLOYED , then those components too will also be unverified by this operation, and so on

recursively. ( See the note about install levels on page below. )

About install levels

The general rule for install levels is that any given component cannot have an install level greater than any of the components that it

depends on.

If a component desires to transition to a higher install level then all its dependent components must successfully transition to the new

install level first.

If a component desires to transition to a lower install level then all components that depend on it must successfully transition to the

new install level first.

15

Page 16: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

2.3 Component copy

In order to maintain compatibility with the JAIN SLEE specification, Rhino does not permit the component references of components installed

using a standard SLEE deployable unit — hereinafter termed "original" components — to be dynamically modified. Rather, a virtual copy of

each component to be modified must be made, and the references of the copied components modified instead. A copied component is still

a SLEE component in its own right, and must have a unique identity within the scope of the component type as for any other component.

The only difference between an original SLEE component and a copied component is from where the component originates in the SLEE. A

copied component uses the same set of interfaces and classes, and inherits the configuration properties such as environment entries, from the

component it is copied from.

Here are some commands for managing copies:

Copy A component can be copied using the copyComponent management operation. For example, using rhino-cons

ole :

[Rhino@localhost:2199 (#0)] help copycomponent copycomponent <type> <source-id> <target-name> <target-vendor> <target-version> [-installlevel <level>] Make a copy of the source component with the target identity. The -installlevel option controls to what degree the copied component is installed after it is created [Rhino@localhost:2199 (#1)] copycomponent sbb name=MySBB,vendor=OpenCloud,version=1.0 MySBB OpenCloud 1.0.1 Component SbbID[name=MySBB=OpenCloud,version=1.0] copied to SbbID[name=MySBB,vendor=OpenCloud,version=1.0.1]

The install level of the copied component can optionally be specified when the copy is made. If not specified, a

default install level of DEPLOYED is used. Specifying an install level of INSTALLED is typically most efficient when

making a copy of a component for use in a later binding operation, and is necessary when copying a component

that itself will not pass verification checks.

Show copy history A copied component may be subsequently copied again, leading to the treelike structure of copies branching

out from the original. The ComponentDescriptorExtensions class in rhino-management included in a

component’s metadata descriptor provides information about the source of a component and what copies have

16

Page 17: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

been made of it. The getdescriptor command in rhino-console reports this information, as shown in the

example below:

[Rhino@localhost:2199 (#0)] getdescriptor sbb name=MySBB,vendor=OpenCloud,version=1.0 For component SbbID[name=MySBB,vendor=OpenCloud,version=1.0]: Deployable unit: DeployableUnitID[url=file:/path/to/deployable-unit.jar] Component source: my-sbb.jar Defined using SLEE version: 1.1 ... Copies made from this component: SbbID[name=MySBB,vendor=OpenCloud,version=1.0.1] ... [Rhino@localhost:2199 (#1)] getdescriptor sbb name=MySBB,vendor=OpenCloud,version=1.0.1 For component SbbID[name=MySBB,vendor=OpenCloud,version=1.0.1]: Copied from: SbbID[name=MySBB,vendor=OpenCloud,version=1.0] ... Original component: SbbID[name=MySBB,vendor=OpenCloud,version=1.0] Copies made from this component: none ...

Remove copied

components

A copied component has an implicit dependency on its original. This means that a deployable unit that has copied

components cannot be uninstalled from the SLEE until all its copied components have been removed. Copied

components are removed using the removeCopiedComponents management operation. For example, in

rhino-console :

[Rhino@localhost:2199 (#0)] help removecopiedcomponents removecopiedcomponents [<type> <url|component-id>]* Remove components that have been copied from another component. Either individual components or a single deployable unit identifier can be specified. In the latter case, all copied components of the DU will be removed [Rhino@localhost:2199 (#1)] removecopiedcomponents sbb name=MySBB,vendor=OpenCloud,version=1.0.1 1 component removed (or) [Rhino@localhost:2199 (#2)] removecopiedcomponents du file:/path/to/deployable-unit.jar The following copied components were removed: SbbID[name=MySBB,vendor=OpenCloud,version=1.0.1]

Find orphaned copied

components

After some copied components have been removed, other copied components may remain that are no longer

referenced by any other component. The findOrphanedCopiedComponents command in rhino-console

can be helpful in finding these components, as shown in the example below:

[Rhino@localhost:2199 (#0)] help findorphanedcopiedcomponents findorphanedcopiedcomponents Find copied components that are no longer referenced by any other component. Components such as services and resource adaptors that sit at

17

Page 18: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

the top of the dependency hierarchy are not included [Rhino@localhost (#1)] findorphanedcopiedcomponents Copied components not used by any other component: SbbID[name=MySBB,vendor=OpenCloud,version=1.0.2] ...

2.4 Dynamic dependency specification

Dynamic component dependencies are specified using a binding descriptor. A binding descriptor is a JSON document that describes the changes

that should be made to the deployment descriptors of one or more components. For example, a binding descriptor may change the root SBB

of a service, or may add a new library reference to an SBB. A binding descriptor can only add to or change existing information contained in a

deployment descriptor; it cannot remove any existing information.

A binding descriptor is a new component type in Rhino. As a component type, a binding descriptor has an identity described by the name, vendor,

and version tuple — like all other SLEE component types. A binding descriptor document may be installed in Rhino as a new type of deployable

entity.

2.4.1 Binding descriptor format

A binding descriptor is a JSON document that must conform to the schema defined by Rhino. The binding descriptor schema can be found in the

doc/dtd directory of a Rhino install. Loosely speaking, a binding descriptor document must contain the declaration of a single JSON object with:

• an optional description property containing an arbitrary string description

• mandatory name , vendor , and version properties

• an optional service property containing a service descriptor

• an optional sbbs property containing an array of zero or more SBB descriptors

• an optional sbbParts property containing an array of zero or more SBB part descriptors

• an optional profileSpecs property containing an array of zero or more profile specification descriptors

• an optional libraries property containing an array of zero or more library descriptors.

Each component descriptor that can be contained by a binding descriptor has a structure based on the corresponding SLEE-defined DTD for

that component type. Only component properties that can be modified by bindings are defined by the schema and can be included in a binding

descriptor.

18

Page 19: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Below is an example of a binding descriptor that can be used to change the root SBB of a service:

{ "description": "Change service's root SBB",

"name": "Example binding descriptor", "vendor": "OpenCloud", "version": "1.0",

"service": { "rootSbb": { "name": "MyOtherSBB", "vendor": "OpenCloud", "version": "1.0" } }}

2.4.2 Managing binding descriptors

A binding descriptor is installed into Rhino much like a SLEE deployable unit. The deployable type option must be used to indicate that the type of

object being installed is a binding descriptor.

Here’s how to install and uninstall them:

Install a binding

descriptor

The example below shows how a binding descriptor can be installed using rhino-console :

[Rhino@localhost:2199 (#0)] install file:/path/to/my-binding-descriptor.json -type bindings Installed: DeployableUnitID[url=file:/path/to/my-binding-descriptor.json]

Install levels on page 12 are not relevant for binding descriptors. Any install level specified when a binding

descriptor is installed is ignored.

An installed binding descriptor document is a deployable unit that contains one binding descriptorcomponent with an identity as specified by the name , vendor , and version properties in the JSON

19

Page 20: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

document. Binding descriptor components do not support Component copy on page 16 operations,as such an operation has little meaning.

Uninstall a binding

descriptor

An installed binding descriptor can be uninstalled in the same way as any other SLEE deployable unit. For

example, using rhino-console :

[Rhino@localhost:2199 (#1)] uninstall file:/path/to/my-binding-descriptor.json uninstalled: DeployableUnitID[url=file:/path/to/my-binding-descriptor.json]

2.4.3 Binding descriptor application

Binding descriptors are applied to components within the scope of a service. That is, a binding descriptor can be associated with a service,

and its effects are propagated to the affected components used by the service. Binding descriptors can be associated with, and subsequently

disassociated from, any service with an install level on page 12 of INSTALLED or VERIFIED . A service with an install level of DEPLOYED must

be undeployed before its binding descriptor associations can be changed.

Binding descriptors can only be associated with a component copy on page 16 service component. If a command is given to associate a

binding descriptor with an original service component, a new copy of the service component will automatically be made by Rhino and the binding

descriptor associated with the copied component instead.

A binding descriptor associated with a service that affects dependent components of the service, such as SBBs or libraries, requires that those

components be copied and the effects of the binding descriptor applied to the copied components. Rhino will automatically copy components

where necessary to fulfil this requirement, according to the following rules:

• If an original component needs its bindings modified, a copy is first made and the copy modified.

• If a copied component needs its bindings modified, and the copied component is not used in any other service, then the copied

component is reused for the new modifications.

• If a copied component needs its bindings modified, but the copied component is in use by some other service, then a new copy is

made and the new copy modified.

• The ripple effect may cause other copies to be generated. For example, if SBB A references SBB B and SBB B is copied and its

bindings modified, then SBB A also needs to be modified with an update to reference the copied SBB B . To do this SBB A may also

need to be copied first as described above.

20

Page 21: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

The component identifiers of copied components may be specified as part of the binding operation, if specific identifiers are desired. If a

component needs to be copied but a component identifier has not been specified for the copy, then Rhino will automatically generate a new

unique component identifier based on the original component’s identifier.

2.4.4 Service binding capabilities

A binding descriptor applied to a service may cause any of the following actions:

• change the root SBB of the service

• modify one or more dependent SBBs by:

• adding new library, profile specification, SBB, and/or SBB part references

• adding new resource adaptor type bindings

• adding new declarative SBB child relations on page 90

• adding new CMP extension interfaces on page 47

• adding new extension usage parameters interfaces on page 94

• adding new environment entries, or changing the values of existing environment entries

• modify one or more dependent SBB parts by:

• adding new library, profile specification, and/or SBB part references

• adding new resource adaptor type bindings

• adding new CMP extension interfaces on page 47

• adding new extension usage parameters interfaces on page 94

• modify one or more dependent profile specifications by:

• adding new library and/or profile specification references

• adding new environment entries, or changing the values of existing environment entries

• changing the definition or options of static queries

• modify one or more dependent libraries by:

• adding new library references.

21

Page 22: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Due to classloader limitations, a profile specification can only have its bindings modified if there are no profile tables, resource adaptorentities, or services with an install level of DEPLOYED , that depend on any profile specification in the same profile specificationcomponent jar present in the SLEE. Attempting to change the bindings of a profile specification that does not meet this criteria willresult in the failure of the binding operation.

2.4.5 Binding conflicts

It is possible that a conflict may arise with a binding descriptor that is associated with a service:

• A binding descriptor may declare a usage parameters interface of type X , as extending a different usage parameters interface type

than a previous definition of X (either in the original deployment descriptor or in another associated binding descriptor).

No conflict arises if X has previously been declared with no extends type , but an associated bindingdescriptor specifies an extends type for X . In this case, the SLEE assumes that X should now extend thespecified type rather than extend nothing.

• A binding may declare an environment entry with name X with a different Java type than a previous definition of X .

If either of these types of conflicts occur, the binding descriptor association fails. The conflict must be resolved before the binding descriptor can

be successfully associated.

Duplicate definitions such as component references do not cause a conflict. For example if the deployment descriptor and one or more binding

descriptors all declare the same library reference, they are simply merged together into a single reference.

2.4.6 Associating a binding with a service

Here’s how to associate a binding descriptor with a service, map target component identifiers of copied component, and disassociate a binding

descriptor from a service:

Associate A binding descriptor is associated with a service using the addBindings operation defined on the ServiceMan

agementMBean . This operation may be invoked in rhino-console , for example, as shown below:

[Rhino@localhost:2199 (#0)] help addservicebinding addservicebinding <service-id> [-binding <binding-descriptor-id>]* [-mapping <map-name>] [-dryrun] Add one or more bindings to a service. The -mapping option specifies a component mapping

22

Page 23: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

created with the createbindingcomponentmap command. The -dryrun option will display the affects the binding operation will make but will not actually commit the changes

The example below associates a binding descriptor with a service:

[Rhino@localhost:2199 (#0)] addservicebinding name=MyService,vendor=OpenCloud,version=1.0 -binding name=MyBinding,vendor=OpenCloud,version=1.0 Bindings added to service ServiceID[name=MyService,vendor=OpenCloud,version=1.0] The following new components were created: SbbID[name=MySbb,vendor=OpenCloud,version=1.0-copy#1] ServiceID[name=MyService,vendor=OpenCloud,version=1.0-copy#1] No components were removed

Create mappings The -mapping argument can be used to specify the target component identifiers of copied components, rather

than have Rhino autogenerate them. In rhino-console such a map is managed using the following additional

commands:

createbindingcomponentmap <map-name> Create a component mapping that can be used with the addservicebinding command. Mappings can be added using the addbindingcomponentmapping command. Created mappings exist only in the client, and will be lost when the client terminates removebindingcomponentmap <map-name> Remove an existing bindings component mapping listbindingcomponentmaps List the current bindings component maps addbindingcomponentmapping <map-name> <source-id> <target-name> <target-vendor> <target-version> Add a bindings mapping from the source component to the target identity removebindingcomponentmapping <map-name> <source-id> Remove a bindings component mapping dumpbindingcomponentmap <map-name> Dump the current mappings in the specified bindings component maps

The following example creates a mapping and uses it to control the component identifier of the SBB copied by the

binding operation:

[Rhino@localhost:2199 (#1)] createbindingcomponentmap mymap Bindings component mapping mymap created [Rhino@localhost:2199 (#2)] addbindingcomponentmapping mymap sbb name=MySbb,vendor=OpenCloud,version=1.0 MySbb OpenCloud 1.0.1 Mapping SbbID[name=MySbb,vendor=OpenCloud,version=1.0] -> SbbID[name=MySbb,vendor=OpenCloud,version=1.0.1] added to mapping mymap [Rhino@localhost:2199 (#3)] dumpbindingcomponentmap mymap Component mappings for mymap: SbbID[name=MyS

23

Page 24: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

bb,vendor=OpenCloud,version=1.0] -> SbbID[name=MySbb,vendor=OpenCloud,version=1.0.1] [Rhino@localhost:2199 (#4)] addservicebinding name=MyService,vendor=OpenCloud,version=1.0 -binding name=MyBinding,vendor=OpenCloud,version=1.0 -mapping mymap Bindings added to service ServiceID[name=MyService,vendor=OpenCloud,version=1.0] The following new components were created: SbbID[name=MySbb,vendor=OpenCloud,version=1.0.1] ServiceID[name=MyService,vendor=OpenCloud,version=1.0-copy#2] No components were removed

As part of a binding operation, the service and all its dependent components transition to theVERIFIED install level. This means that the addition (or removal) of a binding to (or from) a servicemust leave the service in a state that will pass all SLEE verification checks. If any of these checks fail,then the binding operation will also fail.

Disassociate A binding descriptor can be disassociated from a service using the removeBindings operation defined on the

ServiceManagementMBean . This operation may be invoked in rhino-console , for example, as shown

below:

[Rhino@localhost:2199 (#0)] help removeservicebinding removeservicebinding <service-id> [-binding <binding-descriptor-id>]* [-dryrun] Remove one or more bindings from a service. The -dryrun option will display the affects the binding operation will make but will not actually commit the changes

An example of a binding descriptor being disassociated from a service is shown below:

[Rhino@localhost:2199 (#0)] removeservicebinding name=MyService,vendor=OpenCloud,version=1.0-copy#1 -binding name=MyBinding,vendor=OpenCloud,version=1.0 Bindings removed from service ServiceID[name=MyService,vendor=OpenCloud,version=1.0-copy#1] No new components were created The following components were no longer required and were removed: SbbID[name=MySbb,vendor=OpenCloud,version=1.0-copy#1] Service ServiceID[name=MyService,vendor=OpenCloud,version=1.0-copy#1] now has no bindings and may be removed if no longer required

24

Page 25: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

3 CMP Field Enhancements

This page provides an API for the following CMP field enhancements:

3.1 Array support

As an extension to the JAIN SLEE specification, Rhino supports CMP field declarations of arrays for the following SLEE-defined types:

• javax.slee.ActivityContextInterface , and any subclass of this interface

• javax.slee.SbbLocalObject , and any subclass of this interface

• If the abstract getter and setter methods for the CMP field are defined in the SBB abstract class (as opposed to a CMP

extension interface on page 47 ), the corresponding <cmp-field> declaration in the deployment descriptor may not

include an <sbb-alias-ref> element.

• javax.slee.EventContext

• javax.slee.profile.ProfileLocalObject , and any subclass of this interface.

Arrays may be declared with any dimension. Array support is automatic wherever the basic type is supported in CMP fields; in other words, no

user prompt or directive is necessary.

3.2 Serialization enhancements

Rhino introduces a number of enhancements that offer significantly more control and flexibility over how CMP field values are serialized, and much

better serialization performance, when compared with standard Java serialization. These include:

• FastSerializable on page 26

• Encodable on page 28

• Datatype codecs on page 31 .

25

Page 26: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

3.2.1 FastSerializable

The com.opencloud.util.FastSerializable interface provides a simple alternative to the standard Java java.io.Serializable

interface where the exact type of an object to be serialized is known at compile time.

The FastSerializable interface is defined as follows:

package com.opencloud.util;

public interface FastSerializable { public void toStream(java.io.DataOutput stream) throws java.io.IOException;}

A class implementing the FastSerializable interface must provide a public constructor that takes either:

• a single java.io.DataInput argument; or

• a java.io.DataInput argument and a java.lang.ClassLoader argument.

If both constructors are declared by a given class then the two-argument constructor is used.

Serialization of the object is performed by an invocation of the toStream method. Object state must be written to the DataOutput passed as the

input argument. Deserialization is performed by new object instantiation and constructor invocation. Object state can be read from the DataInput

argument. The ClassLoader argument, if present, can be used to resolve any application-specific classes stored in the stream.

Rhino recognises and supports the FastSerializable contract on all CMP fields. Arrays of FastSerializable types of any dimension are

handled automatically by Rhino, and no special treatment is necessary.

While the FastSerializable contract has some similarity to the java.io.Externalizable contract, there are some differences that warrant

discussion:

• FastSerializable operates in terms of data I/O streams, while Externalizable operates in terms of object I/O streams. The

reason for this is that FastSerializable desires to avoid the generally costly serialization overhead that occurs when serializing

arbitrary objects. By limiting the stream I/O to basic datatypes, it forces the user to think about the most performance-efficient manner

in which the object state can be serialized and deserialized.

26

Page 27: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• When FastSerializable types are used in CMP fields, Rhino’s CMP implementation typically determines the type of object to

reconstruct during deserialization at code-generation time, not run time; so care must be taken that objects are restored using the

correct type. Problems occur, for example, if a CMP field is declared in terms of FastSerializable type Foo , but an object of

subclass Bar is stored in the CMP field. The CMP implementation assumes that the CMP field will only store a Foo object, and

will instantiate a Foo object when the CMP field is deserialized, leading to deserialization failures. Making classes that implement

FastSerializable final is good practice, unless this issue is taken into consideration.

• No handling of shared references is performed by the implementation. If the same object is encountered twice during serialization,

then two copies of the object will be stored and subsequently deserialized.

FastSerialize

The com.opencloud.util.FastSerialize class provides some utility functions that may be useful to application developers implementing

their own serialization logic based around FastSerializable .

Example

Below is an example of a FastSerializable type:

import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import com.opencloud.util.FastSerializable;

public final class Person implements FastSerializable { public Person(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; }

public Person(DataInput in, ClassLoader classLoader) throws IOException { firstName = in.readUTF(); lastName = in.readUTF(); age = in.readInt(); }

27

Page 28: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

@Override public void toStream(DataOutput out) throws IOException { out.writeUTF(firstName); out.writeUTF(lastName); out.writeInt(age); }

public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; }

private final String firstName; private final String lastName; private final int age;}

3.2.2 Encodable

The com.opencloud.rhino.cmp.Encodable interface provides a similar contract to that of FastSerializable but is specifically targeted

at types stored in SBB CMP fields. It provides access to utility functions to encode and decode SLEE-specific datatypes that are not defined

as serializable, such as SBB and profile local object references, and an encodable context on page 34 that can be set by an SBB to pass

information to the encoding . decoding methods, such as references to resource adaptor provider objects.

The Encodable interface is defined as follows:

package com.opencloud.rhino.cmp;

import com.opencloud.rhino.cmp.codecs.EncoderUtils;

public interface Encodable { public void encode(java.io.DataOutput out, EncoderUtils utils) throws java.io.IOException;}

A class implementing the Encodable interface must provide a public constructor that takes, in this order: a java.io.DataInput argument, a

java.lang.ClassLoader argument, and a com.opencloud.rhino.cmp.codecs.DecoderUtils argument.

28

Page 29: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Serialization of the object is performed by an invocation of the encode method. Object state must be written to the DataOutput passed as the

input argument. Deserialization is performed by new object instantiation and constructor invocation. Object state can be read from the DataInput

argument. The ClassLoader argument can be used to resolve any application-specific classes stored in the stream.

The constructor and encode methods of an Encodable type are always invoked with the same transaction context used to access or update the

CMP field. This is typically only of consequence if an encodable context is used to provide access to other SBB CMP fields.

EncoderUtils / DecoderUtils

SLEE-defined datatypes such as SBB and profile local objects, activity context interface objects, and event context objects are not defined by the

SLEE specification as being serializable. The SLEE specification does provide provision for storing objects of these types directly into CMP fields;

but the lack of implicit serializability means that, for example, an SBB local object reference cannot be encapsulated within some other object

which is stored into CMP, as object serialization will fail when it reaches the unserializable SBB local object reference.

The EncoderUtils object passed to the encode method provides access to methods that can serialize these SLEE-defined datatypes,

allowing classes that implement the Encodable contract to encapsulate objects of these datatypes and still be storable into CMP fields. The

corresponding DecoderUtils object passed to the decoding constructor provides access to methods that can deserialize these datatypes,

allowing correct object reconstruction during deserialization.

Rhino recognises and supports the Encodable contract on all CMP fields; however the utility methods provided by SleeDatatypeEncoder

and SleeDatatypeDecoder only function under certain conditions:

• Encode and decode of all SLEE-defined datatypes is supported for SBB and SBB Part on page 68 CMP fields.

• Encode and decode of EventContext objects is supported for Activity Context Interface attributes.

• Encode and decode of SLEE-defined datatypes is unsupported in any other case, and invoked methods will throw a

java.lang.UnsupportedOperationException .

Arrays of Encodable types of any dimension are handled automatically by Rhino, and no special treatment is necessary.

Unlike FastSerializable types, CMP fields that store Encodable types may, at runtime, store a subclass of the declared CMP field type

without issue. For example, if a CMP field is declared in terms of Encodable type Foo , an object of subclass Bar may be stored in the CMP field

and it will serialize and deserialize as expected. Deserialization is, however, more efficient if the type of the stored object is the same as the CMP

field type, as reflection must be used to reconstruct a stored object if the type of the stored object differs from the expected type.

29

Page 30: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Like FastSerializable , no handling of shared references is performed by the implementation. If the same object is encountered twice during

serialization, then two copies of the object will be stored and subsequently deserialized.

Example

Below is an example of an Encodable type:

import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import javax.slee.ActivityContextInterface;import com.opencloud.rhino.cmp.Encodable;import com.opencloud.rhino.cmp.codecs.DecoderUtils;import com.opencloud.rhino.cmp.codecs.EncoderUtils;import com.opencloud.rhino.cmp.codecs.SleeDatatypeDecoder;import com.opencloud.rhino.cmp.codecs.SleeDatatypeEncoder;

public final class Relay implements Encodable { public Relay(IncomingSbbLocalObject incoming, OutgoingSbbLocalObject outgoing, ActivityContextInterface aci) { this.incoming = incoming; this.outgoing = outgoing; this.aci = aci; }

public Relay(DataInput in, ClassLoader classLoader, DecoderUtils utils) throws IOException { SleeDatatypeDecoder decoder = utils.getSleeDatatypeDecoder(); incoming = decoder.decodeSbbLocalObject(in); outgoing = decoder.decodeSbbLocalObject(in); aci = decoder.decodeActivityContextInterface(in); messageCount = in.readInt(); }

@Override public void encode(DataOutput out, EncoderUtils utils) throws IOException { SleeDatatypeEncoder encoder = utils.getSleeDatatypeEncoder(); encoder.encodeSbbLocalObject(incoming, out); encoder.encodeSbbLocalObject(outgoing, out); encoder.encodeActivityContextInterface(aci, out);

30

Page 31: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

out.writeInt(messageCount); }

public IncomingSbbLocalObject getIncomingSbb() { return incoming; } public OutgoingSbbLocalObject getOutgoingSbb() { return outgoing; } public ActivityContextInterface getActivityContextInterface() { return aci; }

public void incMessageCount() { messageCount++; } public int getMessageCount() { return messageCount; }

private final IncomingSbbLocalObject incoming; private final OutgoingSbbLocalObject outgoing; private final ActivityContextInterface aci; private int messageCount;}

3.2.3 Datatype codecs

The Encodable contract provides an in-line mechanism for object serialization. That is, code for serialization and deserialization forms part of

the class itself. There may be times, however, when it is desired or necessary for the serialization code to be separated from the class being

serialized. For example, the serialization logic may have common components that can be shared between multiple classes, or the source code

for the class being serialized may not be available to be enhanced to support the FastSerializable on page 26 or Encodable on page 28

serialization contracts.

To support these situations, Rhino allows a datatype codec to be defined and associated with either a CMP field or a serializable class directly.

The datatype codec specifies how objects of the target type are serialized and deserialized, essentially providing a third-person perspective to the

Encodable contract.

A datatype codec must implement the com.opencloud.rhino.cmp.codecs.DatatypeCodec interface. This interface is defined as follows:

package com.opencloud.rhino.cmp.codecs;

import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;

public interface DatatypeCodec<T> {

31

Page 32: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public void encode(T value, DataOutput out, EncoderUtils utils) throws IOException; public T decode(DataInput in, ClassLoader classLoader, DecoderUtils utils) throws IOException;}

A datatype codec class must be public (and static, if an inner class) and implement a public no-argument constructor. The encode method

functions identically to the encode method defined by the Encodable interface, but takes the object to be serialized as an additional argument.

The decode method functions identically to the deserialization constructor required by the Encodable contract, but returns the deserialized

object as the method return result. The generic type parameter T identifies the type of object that the datatype codec is capable of serializing and

deserializing. Generally, a datatype codec does not need to concern itself with encoding or decoding null values, as Rhino will only invoke the

codec for non- null values. There is one exception to this rule, discussed in the Datatype codecs for collections on page 40 section below.

The encode and decode methods are always invoked with the same transaction context used to access or update the CMP field. This is typically

only of consequence if an encodable context on page 34 is used to provide access to other SBB CMP fields.

A datatype codec is associated with the corresponding datatype using the @DatatypeCodecType annotation. This annotation requires the

datatype codec class to be specified as an argument. The annotation can be used either directly on the target class to be serialized, or attached

to a CMP field getter or setter method. If attached to a CMP field getter or setter method of an array type, then the datatype codec need only be

defined in terms of the base array component type. The codec will be invoked for each non- null array element encountered during serialization

or deserialization.

Datatype codecs are supported on all CMP fields where Encodable types are supported, and have the same conditions of use.

The @DatatypeCodecType annotation may not be used on a CMP field getter or setter method where the CMP field is one of the following types,

or is an array of any dimension of one of the following types:

• javax.slee.ActivityContextInterface , and any subclass of this interface

• javax.slee.SbbLocalObject , and any subclass of this interface

• javax.slee.EventContext

• javax.slee.profile.ProfileLocalObject , and any subclass of this interface.

Examples

Below is an example of a datatype codec handling the serialization of class type Customer :

32

Page 33: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import com.opencloud.rhino.cmp.codecs.DatatypeCodec;import com.opencloud.rhino.cmp.codecs.DecoderUtils;import com.opencloud.rhino.cmp.codecs.EncoderUtils;

public class CustomerCodec implements DatatypeCodec<Customer> { @Override public void encode(Customer value, DataOutput out, EncoderUtils utils) throws IOException { ... }

@Override public Customer decode(DataInput in, ClassLoader classLoader, DecoderUtils utils) throws IOException { return ... }}

The datatype codec can be associated directly with the Customer datatype by annotating the class itself as shown below:

@DatatypeCodecType(CustomerCodec.class)public class Customer ...

Alternatively, a CMP field storing a Customer object can be annotated to declare the datatype codec to be used for that CMP field, as shown

below:

public abstract class MySbb implements Sbb { ...

@DatatypeCodecType(CustomerCodec.class) public abstract void setCustomer(Customer customer); public abstract Customer getCustomer();}

The datatype codec can be equally used on a CMP field storing an array of Customer objects, as shown below:

33

Page 34: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public abstract class MySbb implements Sbb { ...

@DatatypeCodecType(CustomerCodec.class) public abstract void setCustomers(Customer[] customers); public abstract Customer[] getCustomers();}

3.2.4 Encodable context

There are a number of use cases where serialization and/or deserialization of a CMP object requires access to resources that the Encodable on

page 28 and DatatypeCodec on page 31 encode and decode methods may not natively have access to. For example, deserialization of

a stored network message may require access to the owning resource adaptor provider object to reconstruct the correct object graph. To solve

this problem, Rhino defines the concept of an encodable context . An encodable context can provide access to the resources that the encode and

decode methods need in order to fulfill their function.

Encodable context definition

The encodable context required for any given Encodable or DatatypeCodec type may be defined as either a class or interface, though it

is strongly recommended that the context be defined as an interface. The reason for this is to allow the provider of the context to more easily

combine contexts required by multiple Encodable or DatatypeCodec types used in different CMP fields into a single implementation object.

An encodable context may provide read access to other CMP states, but should not provide write access to any CMP state. SLEE behaviour is

undefined if arbitrary CMP fields are modified during the encode or decode of another CMP field. Otherwise, there are no specific requirements or

restrictions about what an encodable context may provide access to.

Below is an example of an encodable context interface:

import org.jainslee.resources.diameter.ro.RoProviderFactory;

public interface RoProviderContext { public RoProviderFactory getRoProviderFactory(); public Tracer getTracer(); public int getSomeContextValue();}

34

Page 35: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

An Encodable or DatatypeCodec object obtains an encodable context object from the EncoderUtils argument passed to the encode

method, or from the DecoderUtils argument passed to the deserialization constructor (for Encodables ) or decode method (for

DatatypeCodecs ).

Encodable context provider

If an Encodable or DatatypeCodec type is a consumer of an encodable context, then there must be a corresponding provider of the context.

Only SBBs currently support providing an encodable context object for use by CMP fields declared by itself or any dependent SBB part. An SBB

sets the encodable context using the setEncodableContext method on its com.opencloud.rhino.slee.RhinoSbbContext object (a

Rhino extension of javax.slee.SbbContext ):

package com.opencloud.rhino.slee;

public interface RhinoSbbContext extends SbbContext { public <T> void setEncodableContext(T context) throws SLEEException;

...}

The encodable context object set by the SBB must implement all encodable context types expected by the Encodable or DatatypeCodec

types that it uses, so that each Encodable or DatatypeCodec type may typecast the object to the encodable context type that it expects.

An encodable context object is scoped to an SBB object; therefore the recommended place to initialise the encodable context is in the SBB’s

setSbbContext method.

Below is an example implementation of the RoProviderContext encodable context interface shown above:

import javax.naming.InitialContext;import javax.slee.Sbb;import javax.slee.SbbContext;import com.opencloud.rhino.slee.RhinoSbbContext;import org.jainslee.resources.diameter.ro.RoProviderFactory;

public abstract class MySbb implements Sbb { public void setSbbContext(SbbContext context) { RhinoSbbContext rhinoContext = (RhinoSbbContext)context;

35

Page 36: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

final RoProviderFactory roProviderFactory = new InitialContext().lookup(...); final Tracer encodableContextTracer = context.getTracer(...); rhinoContext.setEncodableContext(new RoProviderContext() { @Override public RoProviderFactory getRoProviderFactory() { // return provider factory from JNDI return roProviderFactory; } @Override public Tracer getTracer() { // return tracer for encode/decode methods to use return encodableContextTracer; } @Override public int getSomeContextValue() { // return value from SBB CMP return MySbb.this.getSomeContextValue(); } });

.... }

// cmp field declaration public abstract void setSomeContextValue(int value); public abstract int getSomeContextValue();

...}

Since other persistent entities, such as profiles and activity context interface objects, do not currently support the provision of an encodable

context object, Encodable or DatatypeCodec types that require an encodable context cannot be used with these persistent entities. The

getEncodableContext method defined in the EncoderUtils and DecoderUtils interfaces will always return null for these types of

persistent entities.

36

Page 37: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

3.2.5 Codecs for Java collection types

Rhino natively supports FastSerializable and Encodable types, and types using a DatatypeCodec , on array-type CMP fields. Each non-

null array element is individually serialized and deserialized as appropriate. However there are times when using a Java Collections Framework

type, such as List or Set in a CMP field, is preferable to using an array; but retaining the serialization benefits provided by the element type is

desired.

To answer this, Rhino provides a set of base classes that provides a framework for efficient serialization of Encodable on page 28 , List ,

Set , and Map types, and additional datatype codec annotations to simplify the common use cases.

Encodable collections

Rhino provides three base abstract classes to support efficiently serialized collections:

• com.opencloud.rhino.util.EncodableList — implements java.util.List and

com.opencloud.rhino.cmp.Encodable

• com.opencloud.rhino.util.EncodableSet — implements java.util.Set and

com.opencloud.rhino.cmp.Encodable

• com.opencloud.rhino.util.EncodableMap — implements java.util.Map and

com.opencloud.rhino.cmp.Encodable .

Each of these classes wraps an implementation of the corresponding collection type, and implements the Encodable contract to manage the

serialization and deserialization of that collection. To use any of these as a CMP field type, the application developer must implement a concrete

class extending from the relevant base class, taking into account the following rules and considerations.

Constructors

A concrete subclass must provide a public constructor satisfying the Encodable contract which delegates to the equivalent protected constructor

in the base class. The subclass should also provide at least one general user constructor that delegates to one of the base class public

constructors, such as the no-argument constructor. A subclass of EncodableList may also need to provide a constructor suitable for use with

the implementation of the abstract newInstance method.

37

Page 38: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Implementation of writer / reader methods

A concrete subclass must provide the implementation of the abstract writer and reader methods defined by the base class. These methods are

responsible for the encoding and decoding of individual collection elements, map keys, or map values, as appropriate.

Implementation of EncodableList newInstance method

The java.util.List interface includes a method, subList , which returns a view of a portion of the source list. The EncodableList requires

that a subclass implements the newInstance method it defines to facilitate the implementation of this method. The newInstance method

should return a new instance of the concrete class which wraps the list provided by the method argument. Delegating to the EncodableList

constructor defined with the same arguments as the newInstance method is the recommended approach.

Managing null elements, keys, and values

The default implementation of EncodableList and EncodableSet assumes that null elements will not occur in the collection. The default

implementation of EncodableMap assumes that null keys will not occur in the map, but that null values might. The consequence of this is that

if a null element occurs in a list or set, or null key occurs in a map, then during serialization the corresponding writer method will be asked to

encode the null object. While this is not problematic, it means that the writer and reader methods need to perform additional work to handle the

presence of null objects in the stream they write to or read from.

To simplify the code required of the writer and reader methods when null objects are expected by a given datatype, a subclass may change

the default behaviour of the base class by overriding the manageNullElements method in EncodableList and EncodableSet , or the

manageNullKeys and manageNullValues methods in EncodableMap . If these methods return true , then the base class will check for null

objects of the corresponding type and handle them internally, only invoking the writer and reader methods for non- null objects. If null objects

are never expected, or not supported by the underlying backing store (or the writer and reader methods will handle null objects), then these

methods may return false , resulting in a slightly smaller serialization data stream that doesn’t include the extra information required for null

checks.

Below is an example of subclass of EncodableList that stores a list of strings with possible null elements:

import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import java.util.List;import com.opencloud.rhino.cmp.codecs.DecoderUtils;

38

Page 39: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import com.opencloud.rhino.cmp.codecs.EncoderUtils;import com.opencloud.rhino.cmp.codecs.SimpleDatatypeCodecs;import com.opencloud.rhino.util.EncodableList;

public class StringList extends EncodableList<String> { // general user constructor // since we implicitly delegate to the default superclass constructor, // the underlying collection will be an ArrayList public StringList() {}

// constructor required by the Encodable contract public StringList(DataInput in, ClassLoader cl, DecoderUtils utils) throws IOException { super(in, cl, utils); }

// constructor used by newInstance() protected StringList(BackingStore backingStore, List<String> list) { super(backingStore, list); }

@Override protected StringList newInstance(BackingStore backingStore, List<String> list) { return new StringList(backingStore, list); }

@Override protected void writeElement(String element, DataOutput out, EncoderUtils utils) throws IOException { CODEC.encode(element, out, utils); }

@Override protected String readElement(DataInput in, ClassLoader cl, DecoderUtils utils) throws IOException { return CODEC.decode(in, cl, utils); }

@Override protected boolean manageNullElements() { // null elements are possible // tell the superclass to deal with them so we don't have to

39

Page 40: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

return true; }

// use predefined datatype codec for encode and decode private static final SimpleDatatypeCodecs.StringCodec CODEC = new SimpleDatatypeCodecs.StringCodec();}

Below is an example of a CMP field declared in terms of this datatype:

public abstract void setNames(StringList names);public abstract StringList getNames();

Datatype codecs for collections

In many use cases, the implementation of an Encodable collection type would look strikingly similar to the example shown in the previous

section. Most of the implementation code is boilerplate, even more so if the writer and reader methods simply delegate to another datatype codec

class. To simplify application development, Rhino provides an alternative through the use of annotations on the CMP field getter or setter method:

• An EncodableList implementation can be substituted with a @ListCodecType annotation.

• An EncodableSet implementation can be substituted with a @SetCodecType annotation.

• An EncodableMap implementation can be substituted with a @MapCodecType annotation.

These annotations have only two minor restrictions:

1. Element, key, and value encoding and decoding must be implemented using datatype codecs on page 31 .

2. Generic type parameters aside, an annotated CMP field must be declared in terms of the base collection interface type, that is:

java.util.List , java.util.Set , or java.util.Map , or an array of any dimension of this type.

• If the CMP field type is scalar, any implementation class of the declared CMP field type may be passed as a parameter to the

CMP field setter method, for example: a java.util.ArrayList or java.util.HashSet . However, no assumption can

be made about the type of object returned from the CMP field getter method, other than it implements the interface declared

as the CMP field type. For example, if the CMP field type is java.util.List , a java.util.ArrayList may be passed

to the CMP field setter method; but it cannot be assumed that a java.util.ArrayList will be returned from the CMP field

getter method.

40

Page 41: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• If the CMP field type is an array, any implementation class of the base component type of the declared CMP field array

type may be passed as array elements. However, no assumption can be made about the type of objects returned as array

elements from the CMP field getter method, other than they implement the interface declared as the array base component

type.

Below is an example of how the StringList CMP field example from the previous section could be simplified by using the @ListCodecType

annotation:

@ListCodecType(codec = SimpleDatatypeCodecs.StringCodec.class, manageNullElements = true)public abstract void setNames(List<String> names);public abstract List<String> getNames();

The annotations provide a similar level of configurability as can be achieved by manual implementation. For example, the underlying collection

type and management of null objects can be specified as annotation parameters.

Datatype codecs and null objects

If a collection datatype codec annotation indicates that null objects should not be managed internally by Rhino, and null objects occur in the

corresponding data set, then this is one specific case where the serializing datatype codec is expected to handle and manage the null value

itself during serialization and deserialization. For simplicity reasons, it is highly recommended that Rhino be asked to manage null objects when

they are expected through appropriate annotation parameters.

3.2.6 Predefined datatype codecs

Rhino provides two sets of predefined datatype codecs:

• com.opencloud.rhino.cmp.codecs.SimpleDatatypeCodecs — provides codecs for the primitive type wrapper classes and

java.lang.String

• com.opencloud.rhino.cmp.codecs.SleeDatatypeCodecs — provides codecs for JAIN SLEE-defined types such as

javax.slee.SbbLocalObject and javax.slee.ActivityContextInterface .

These predefined codecs can be particularly useful when using datatype codecs for collections on page 40 that store simple types such as

java.lang.Integer or java.lang.String .

41

Page 42: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

3.3 Initial values

Often it is necessary, when a new persistent entity (such as an SBB entity) is created, to initialise various CMP fields to a value different than the

standard Java default. For example: a CMP field storing a counter may need to be initialised to 1 instead of the default value of 0; a CMP field

storing an array may need to be initialised to an empty array rather than default null ; or a CMP field storing a list may need to be initialised to an

empty list. The standard way to achieve this is to add the necessary CMP setter method invocations to the entity’s create lifecycle method; this is

acceptable, but means that the initial value is separated from the CMP field declaration, making the code less obvious than it could be. Also this

technique doesn’t work if, for example, an arbitrary CMP extension interface on page 47 is linked in to the SBB — the SBB needs to know a

priori what CMP fields need initialising — which means CMP fields in CMP extension interfaces dynamically added after compilation cannot be

initialised this way.

To solve this problem, Rhino introduces an annotation that can be used to specify the initial value for a CMP field.

3.3.1 Initial value fields

The initial value for a CMP field can be declared by annotating either the CMP field getter or setter method with the

@com.opencloud.rhino.cmp.InitialValueField annotation. The annotation references, either implicitly or explicitly by parameter, a

class field that contains the initial value for the CMP field. This mechanism means that the initial value can be constructed by any legal Java

means, and initial values for any arbitrarily complex CMP field type can be declared without issue.

If the annotation does not explicitly name a class field to use as the initial value, then a default name of _initial + the CMP field name, with the

first letter capitalised, is assumed. For example, for a CMP field with the name foo , the default initial value field name is _initialFoo .

The initial value class field must:

• be public, static, and final

• be visible in the scope of the annotated CMP field accessor method

• have a type that is assignable to the CMP field.

The @InitialValueField annotation may be used on:

• an SBB abstract class CMP field getter or setter method

• an SBB or SBB part CMP extension interface CMP field getter or setter method

42

Page 43: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• a profile CMP interface CMP field getter or setter method.

It is illegal to use this annotation on both the getter and setter methods for the same CMP field, or to declare an initial value for the same CMP

field multiple times. For example, if a given CMP field is declared both in an SBB abstract class and an SBB CMP extension interface, only one

CMP field declaration may be annotated with an initial value declaration. It is legal, however, for example, for two separate SBB CMP extension

interfaces to both extend from a common interface that declares a CMP field with an initial value, as the initial value has only been declared once

by the parent interface.

The @InitialValueField annotation may not be used on a CMP field getter or setter method where the CMP field is one of the following types,

or is an array of any dimension of one of the following types:

• javax.slee.ActivityContextInterface , and any subclass of this interface

• javax.slee.SbbLocalObject , and any subclass of this interface

• javax.slee.EventContext

• javax.slee.profile.ProfileLocalObject , and any subclass of this interface.

A error occurs at deployment time if any of the above constraints are violated.

SLEE behaviour is undefined if an object referenced by an initial value class field is mutated at any time. A newly created persistent entity

containing the CMP field could be initialised with either the original initial value or the modified initial value at the discretion of the SLEE

implementation. It is generally advised that initial values be immutable; though in some cases this will not be possible.

Examples

Below is an example where the initial value field is explicitly named by the annotation:

@InitialValueField("aValue")public abstract void setIntValue(int value);public abstract int getIntValue();public static final int aValue = 42;

Below is an example where the initial value field is not explicitly specified, so the default field name is assumed:

@InitialValueFieldpublic abstract void setListValue(List<String> value);

43

Page 44: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public abstract List<String> getListValue();public static final List<String> _initialListValue = new ArrayList<String>(5);

3.4 Pass-by-reference

The JAIN SLEE 1.1 specification, as written, prescribes that CMP fields have pass-by-value semantics. This means that when an object value

is stored in a CMP field, the SLEE will make and store a copy of that value, rather than store the original value. Similarly when a stored value is

retrieved from a CMP field, the SLEE will name a copy of the stored value and return the copied value. The effect of this is that the stored object

is unaffected by any subsequent changes made by the application to the original or retrieved object — a value retrieved from the CMP field will

always have the exact same state as it did when stored in the CMP field.

Generally speaking, this is desired behaviour, and it makes application code easier to understand. However there are times when pass-by-value

semantics get in the way of efficient programming, requiring additional coding to work around the limitations of these semantics. As an example,

consider an application that needs to use some unchanging session state across multiple transactions. The correct SLEE technique here is to

store the state in a CMP field, then retrieve that state in each transaction as required. Unfortunately the pass-by-value semantics mean that the

application incurs the overhead of a stored value copy every time it retrieves the value from the CMP field, even though the stored value is never

changed. A typical workaround to avoid this overhead is to:

1. create an instance variable which caches a reference to the stored value

2. add alternative getter and setter methods which check the cache first

3. include code in the relevant lifecycle callback methods to clear any cached reference when appropriate…

…all of which is cumbersome, particularly when there are many CMP fields that require this treatment.

To simplify the application developer’s effort in situations like these, Rhino introduces the option to declare pass-by-reference semantics to CMP

fields.

3.4.1 Reference scopes

Pass-by-reference may be declared with one of three reference scopes: TRANSACTIONAL , WHILE_READY , or PERMANENT .

The TRANSACTIONAL and WHILE_READY reference scopes operate in similar ways. An intermediate reference cache is used to store the

CMP field value during a transaction. If the CMP field is written to, the cache simply stores the reference to the stored value. If the CMP field is

44

Page 45: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

read, then the reference stored by the cache is returned. The actual stored value is only written back to persistent storage, and thus a copy is

made, when the transaction commits; and that value is only read back from persistent storage if the CMP field is read by the application and the

cache has been invalidated. The difference in the two reference scopes lies in when the cache is invalidated. When using the TRANSACTIONAL

reference scope, the reference cache is invalidated whenever a bounding transaction completes, either by commit or rollback. When using

the WHILE_READY reference scope, the reference cache is invalidated only when the owning container object (such as an SBB object) leaves

the READY state and is thus disassociated from the persistent entity, or transaction rollback occurs and the owning container object needs to

resynchronise with persistent state.

The PERMANENT reference scope completely removes any pass-by-value semantics. Any value stored in the CMP field is stored by reference

only. Unlike other reference scopes, a permanent reference loses all transactional semantics. Any changes made to the referenced object will

persist irrespective of whether the current transaction commits or rolls back. As such, permanent references are best suited to objects that are

unlikely to change during the lifetime of an application entity, for example: parts of input network messages that must be retained across event

handler transaction boundaries, but serialization of those messages is undesirable.

This reference scope should not be used in replicated SBBs, as object references naturally cannot extend beyond a single JVMboundary; the semantics of such a configuration are undefined.

Declaration

Pass-by-reference semantics are declared using the @com.opencloud.rhino.cmp.PassByReference annotation. This annotation may be

used on:

• an SBB abstract class CMP field getter or setter method

• an SBB or SBB Part on page 68 CMP extension interface on page 47 CMP field getter or setter method

• an SBB abstract class itself

• an SBB or SBB part CMP extension interface.

If the annotation is used on a class or interface declaration, then its meaning is applied to all CMP fields declared in the class or interface, and

also any subclass if the annotation’s inherited attribute is set to true . An individual CMP field may override any pass-by-reference semantics

inherited from a class or interface annotation by being annotated itself with a different reference scope. The reference scope DISABLED can also

be used in this case to remove any inherited pass-by-reference semantics from the CMP field.

It is illegal for a single CMP field’s getter and setter methods to be annotated with different reference scopes.

45

Page 46: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

A @PassByReference annotation with WHILE_READY or PERMANENT scope may not be used on a CMP field getter or setter method where the

CMP field is one of the following types, or is an array of any dimension of one of the following types:

• javax.slee.ActivityContextInterface , and any subclass of this interface

• javax.slee.SbbLocalObject , and any subclass of this interface

• javax.slee.EventContext

• javax.slee.profile.ProfileLocalObject , and any subclass of this interface.

Additional considerations

• If pass-by-reference semantics are desired for a CMP field that holds, either directly or indirectly, a reference to a SLEE-defined

object that is only valid in the transaction it was materialised (for example an SbbLocalObject , ProfileLocalObject ,

ActivityContextInterface , or EventContext ), then the reference scope must be limited to TRANSACTIONAL to avoid

runtime application failures. Note that if a CMP field directly storing one of these types inherits pass-by-reference semantics from

a class or interface annotation, Rhino will automatically limit the scope to TRANSACTIONAL for that CMP field. This means it is not

necessary to specifically annotate a CMP field directly storing one of these types if the inherited scope is wider — the correct scope

will be used automatically.

• The @PassByReference annotation naturally has no effect on CMP fields that store primitive types. Primitive types are always

stored by value.

• The @PassByReference annotation also has no effect on CMP fields that store types that Rhino understands to be immutable, such

as java.lang.Integer (and other primitive type wrappers), java.lang.String , javax.slee.Address , and so on… nor any

class that implements com.opencloud.util.Immutable . Immutable types are always stored by reference.

Examples

Below is an example of how a CMP field annotation declaring pass-by-reference semantics can be applied using the default ( WHILE_READY )

reference scope:

@PassByReferencepublic abstract void setValue(FooValue value);public abstract FooValue getValue();

46

Page 47: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Below is an example of how a CMP field annotation declaring pass-by-reference semantics can be applied using the TRANSACTIONAL reference

scope:

@PassByReference(scope = PassByReference.Scope.TRANSACTIONAL)public abstract void setValue(FooValue value);public abstract FooValue getValue();

Below is an example of how an SBB abstract class annotation declaring pass-by-reference semantics can be used to apply the semantics to all

CMP fields, unless otherwise indicated, using the default ( WHILE_READY ) reference scope. These pass-by-reference semantics will also be

inherited by any subclass of this SBB abstract class.

@PassByReference(inherited = true)public abstract class MySbb implements Sbb { ...

// this CMP field will automatically be demoted to use the TRANSACTIONAL reference scope public abstract void setSbbObject(SbbLocalObject sbb); public abstract SbbLocalObject getSbbObject();

// this CMP field will revert to pass by value semantics @PassByReference(scope = PassByReference.Scope.DISABLED) public abstract void setValue(FooValue value); public abstract FooValue getValue();}

3.5 CMP extension interfaces

The SLEE specification requires the SBB CMP fields be defined using abstract getter and setter methods. For example, the SBB CMP field named

firstName of type java.lang.String must have the following method declarations in the SBB abstract class:

public abstract void setFirstName(String firstName);public abstract String getFirstName();

Rhino allows SBB CMP fields alternatively to be defined in separate CMP extension interfaces. A CMP extension interface is simply an interface

that declares methods related only to CMP fields. One use of a CMP extension interface is to allow an SBB to store additional state that may not

47

Page 48: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

be known when the SBB abstract class is developed. For example, the SBB build process may allow additional components to be "plugged in" to

the base SBB, each of which may require its own CMP state. The plug-in components can define the CMP state they need using CMP extension

interfaces; then these interfaces can be declared in the SBB deployment descriptor when the SBB is packaged.

CMP extension interfaces are also the sole mechanism by which an SBB part on page 68 component can define CMP fields.

The firstName CMP field example above could be defined in a CMP extension interface as shown below:

public interface MySbbCMPInterface { public void setFirstName(String firstName); public String getFirstName();

...}

A CMP extension interface may also optionally include has and reset methods for each CMP field.

• The has method determines if a value for the CMP field is present. Primitive types always have a value, so this method will always

return true for a CMP field of a primitive type. For CMP fields storing object types, this method returns true if the CMP field has

been assigned a non- null value. While this method is generally for convenience only, a has method can offer the potential for

better-performing code when only the presence of a value in the CMP field is required to be known, as the implementation does not

necessarily require the stored CMP field value to be deserialized in order to test for a non-null value.

• The reset method resets the CMP field value to its initial value. The initial value is determined by an @InitialValueField

on page 42 annotation, if present. Otherwise, the Java-defined default initial value for the field type is used; for example: 0 for

numeric primitives, null for object references.

Adding the has and reset methods to the MySbbCMPInterface example shown above results in the interface shown below:

public interface MySbbCMPInterface { public void setFirstName(String firstName); public String getFirstName();

// returns true if firstName has an assigned non-null value // effectively equivalent to: getFirstName() != null public boolean hasFirstName();

48

Page 49: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

// effectively equivalent to: setFirstName(null) public void resetFirstName();

...}

Below is an example of a how the reset method is influenced by an @InitialValueField annotation:

public interface MySecondSbbCMPInterface { @InitialValueField public void setNames(String[] names); public String[] getNames(); public static final String[] _initialNames = new String[0];

// effectively equivalent to: setNames(_initialNames) public void resetNames();

...}

A CMP extension interface must be public, and optionally may extend the com.opencloud.rhino.cmp.CMPFields on page 51 interface.

A single SBB or SBB part may declare as many CMP extension interfaces as desired. An SBB declares its CMP extension interfaces in the

oc-sbb-jar.xml extension deployment descriptor, while an SBB part declares its CMP extension interfaces in the oc-sbb-part-jar.xml

deployment descriptor. Since a CMP extension interface defines only CMP fields, an SBB deployment descriptor does not need to specify <cmp-

field> elements for any CMP field defined only in a CMP extension interface. The CMP fields will be determined by class introspection.

All methods defined in a CMP extension interface are mandatory transactional methods. If they are invoked without a valid transaction

context, a javax.slee.TransactionRequiredLocalException will be thrown. In addition, these methods may only be invoked

on an SBB or SBB part object that has been assigned to an SBB entity, or is in the process of being assigned to an SBB entity using the

sbbCreate method. If the SBB or SBB part object is not assigned to an SBB entity (with the exclusion of the sbbCreate method), a

java.lang.IllegalStateException is thrown.

49

Page 50: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

An SBB or SBB part obtains access to the CMP fields defined in CMP extension interfaces using a com.opencloud.rhino.cmp.CMPFields

object. The CMPFields object may be typecast to any CMP extension interface declared by the SBB or SBB part, regardless of whether or not

the CMP extension interface extends the CMPFields interface, thus exposing the CMP field accessor methods defined by the interface.

The CMP fields defined by an SBB in its SBB abstract class, in any CMP extension interfaces, and in any CMP extension interfaces used by

dependent SBB parts, all share the same namespace. As such, if the same CMP field is defined in multiple places, for example in the SBB

abstract class and in a CMP extension interface, then it must be declared with the same type. All these CMP accessor methods will refer to the

same underlying SBB CMP field.

3.6 Arbitrary CMP fields

There are sometimes occasions when an SBB needs to store arbitrary CMP state which cannot be predetermined at development time. For

example, arbitrary session state could be created in response to interactions with some other network element. The typical response is to define

a CMP field that stores a map and store the session state in the map as key, value pairs. This is an acceptable solution; however, serialization of

the stored map value can be a performance hit if not explicitly managed; and even then a change to any mapped value requires serialization of the

entire map as it is read from CMP, updated, then rewritten to CMP.

To help in these situations, Rhino allows an SBB or SBB part to optionally support arbitrary CMP fields. Arbitrary CMP fields are simply CMP

fields that have not been explicitly defined in the SBB abstract class or any CMP extension interface. Support for arbitrary CMP fields is disabled

by default but can be enabled using the arbitrary-cmp-fields-allowed attribute in the oc-sbb-jar.xml SBB extension deployment

descriptor or oc-sbb-part-jar.xml SBB part deployment descriptor. Note that if an SBB has a dependency on an SBB part that has enabled

support for arbitrary CMP fields, then support for arbitrary CMP fields extends back to the SBB and all its dependent SBB parts. It is not possible

for an SBB or SBB part to override a positive setting of this support from some other dependent SBB part (or the SBB itself in the case of an SBB

part).

Arbitrary CMP fields have only a few basic rules and restrictions:

• Arbitrary CMP fields must have a non-null name. Any non-null name is valid, including a zero-length name.

• An arbitrary CMP field cannot have the same name as a CMP field predefined in the SBB abstract class or any CMP extension

interface on page 47 .

50

Page 51: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• An arbitrary CMP field is only deemed to exist if it has an assigned non- null value. An existing arbitrary CMP field ceases to exist if

assigned a null value.

• Any non- null value assigned to an arbitrary CMP field must be serializable using standard Java serialization. FastSerializable on

page 26 types are also supported. Encodable on page 28 types and those annotated with @DatatypeCodec , however, are

not currently supported. FastSerializable should be used instead where possible.

• Arbitrary CMP fields always exhibit pass-by-value semantics as per standard JAIN SLEE-defined CMP field behaviour. Pass-by-

reference on page 44 is not supported for these CMP fields.

Arbitrary CMP fields are accessed and managed using a CMPFields on page 51 object.

3.7 The CMPFields interface

The CMPFields interface provides a means to access CMP fields indirectly by name, access metadata about CMP fields, and obtain information

about and determine which CMP fields currently have a value. Arbitrary CMP fields on page 50 are also managed using a CMPFields object.

The CMPFields interface is shown below:

package com.opencloud.rhino.cmp;

public interface CMPFields { public <T> T get(String name) throws NullPointerException, UnrecognisedFieldNameException, ClassCastException; public <T> void set(String name, T value) throws NullPointerException, UnrecognisedFieldNameException, ClassCastException; public boolean has(String name) throws NullPointerException, UnrecognisedFieldNameException; public void reset(String name) throws NullPointerException, UnrecognisedFieldNameException; public void reset(); public Class<?> typeOf(String name) throws NullPointerException, UnrecognisedFieldNameException; public boolean isPredefined(String name) throws NullPointerException; public Set<String> predefinedNames(); public Set<String> keySet();

51

Page 52: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public Set<Map.Entry<String,Object>> entrySet();}

The get , set , has , and parameterised reset methods allow any CMP field to be accessed by name parameter. These methods provide

an alternative access mechanism for CMP fields predefined in the SBB abstract class or a CMP extension interface on page 47 . These

methods also allow arbitrary CMP fields to be created and managed if support for this feature has been enabled. Predefined and arbitrary

CMP fields all share the same namespace. If any of these methods are invoked with a name parameter that matches a predefined CMP

field name, then the name refers to the predefined CMP field; otherwise it refers to an arbitrary CMP field. These methods throw an

UnrecognisedFieldNameException if the name refers to an arbitrary CMP field, but support for arbitrary CMP fields has not been enabled for

the SBB.

When any of these methods are used to access a predefined CMP field, the invocation is equivalent to the corresponding CMP field method

declaration. The example below illustrates this point:

public abstract class MySbb implements Sbb { public abstract void setFirstName(String firstName); public abstract String getFirstName();

public void someMethod() { CMPFields cmpFields = ...

// set CMP field to "Alice" setFirstName("Alice");

// returns "Alice" String firstName = cmpFields.get("firstName");

// set CMP field to "Bob" cmpFields.set("firstName", "Bob");

// returns "Bob" firstName = getFirstName();

// as the CMP field currently contains a value, // this will reset the CMP field to its initial value null if (cmpFields.has("firstName") { cmpFields.reset("firstName");

52

Page 53: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

}

// returns null firstName = getFirstName();

... }

...}

The unparameterised reset method resets all predefined CMP fields to their initial value and removes all arbitrary CMP fields that exist. This

method effectively returns the SBB CMP state to as it was when the SBB entity was first created.

The typeOf method returns the Java class type of the named CMP field. For a predefined CMP field the return value is equal to the class used

in its CMP field method declarations. For an arbitrary CMP field, this method returns the class of the value stored in the CMP field. The arbitrary

CMP field must exist for this method to return a successful result, otherwise an UnrecognisedFieldNameException is thrown.

The isPredefined method returns true if the name corresponds with a predefined CMP field, and false otherwise. The predefinedNames

method returns a set containing the names of all predefined CMP fields.

The keySet method returns a set containing the names of all CMP fields that currently have a value. The entrySet method returns a map

containing the names and values of all CMP fields that currently have a value. The CMP fields that are deemed to have a value include:

• any predefined CMP field of a primitive type

• any predefined CMP field of an object type that currently has a non- null value

• any arbitrary CMP field that currently exists.

All methods defined in the CMPFields interface are mandatory transactional methods. If they are invoked without a valid transaction

context, a javax.slee.TransactionRequiredLocalException will be thrown. In addition, these methods may only be invoked

on an SBB or SBB part object that has been assigned to an SBB entity, or is in the process of being assigned to an SBB entity using the

sbbCreate method. If the SBB or SBB part object is not assigned to an SBB entity (with the exclusion of the sbbCreate method), a

java.lang.IllegalStateException is thrown.

53

Page 54: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

3.7.1 CMPFields object

An SBB obtains a CMPFields object from its com.opencloud.rhino.slee.RhinoSbbContext object (a Rhino extension of

javax.slee.SbbContext ). An SBB part obtains a CMPFields object from its com.opencloud.rhino.slee.sbbpart.SbbPartContext

object.

A CMPFields object may be typecast to any CMP extension interface on page 47 declared by the SBB or any of its dependent SBB parts,

regardless of whether or not the CMP extension interface extends the com.opencloud.rhino.cmp.CMPFields interface.

54

Page 55: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

4 Miscellaneous SLEE Application API Enhancements

This page details the following enhancements to SLEE APIs, which Rhino provides for SLEE applications:

4.1 SbbContext interface extensions

Rhino provides an extension to the standard javax.slee.SbbContext interface with the com.opencloud.rhino.slee.RhinoSbbContext

interface. The RhinoSbbContext interface provides additional functionality to SBBs running in Rhino. The RhinoSbbContext interface is as

follows:

package com.opencloud.rhino.slee;

import java.util.Map;import javax.slee.SLEEException;import javax.slee.Sbb;import javax.slee.SbbContext;import javax.slee.TransactionRequiredLocalException;import javax.slee.TransactionRolledbackLocalException;import com.opencloud.rhino.cmp.CMPFields;import com.opencloud.rhino.cmp.Encodable;import com.opencloud.rhino.cmp.codecs.DatatypeCodec;import com.opencloud.rhino.cmp.codecs.DecoderUtils;import com.opencloud.rhino.cmp.codecs.EncoderUtils;import com.opencloud.rhino.facilities.Tracer;import com.opencloud.rhino.facilities.childrelations.ChildRelationFacility;import com.opencloud.rhino.slee.environment.JndiBinding;

public interface RhinoSbbContext extends SbbContext { public String getConvergenceName() throws TransactionRolledbackLocalException, IllegalStateException, SLEEException;

public Tracer getTracer(String tracerName) throws NullPointerException, IllegalArgumentException, SLEEException;

55

Page 56: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public RhinoActivityContextInterface[] getActivities() throws TransactionRequiredLocalException, IllegalStateException, SLEEException;

public RhinoActivityContextInterface[] getActivities(Class<?> type) throws NullPointerException, TransactionRequiredLocalException, IllegalStateException, SLEEException;

public ChildRelationFacility getChildRelationFacility() throws SLEEException;

public CMPFields getCMPFields() throws SLEEException;

public Map<String,JndiBinding> getJndiBindings() throws SLEEException;

public <T> void setServiceContext(T context) throws SLEEException;

public <T> T getServiceContext() throws SLEEException;

public <T> void setEncodableContext(T context) throws SLEEException;}

4.1.1 RhinoSbbContext interface getConvergenceName method

The getConvergenceName method returns the convergence name that the SBB entity was created with. The value returned from this method is

a vendor-specific string that uniquely identifies the initial event selector conditions that led to the SBB entity’s creation.

This method only returns a non- null value if invoked on a RhinoSbbContext object belonging to a root SBB entity.

4.1.2 RhinoSbbContext interface getTracer method

The getTracer method overrides the same method from SbbContext to return a Rhino-specific extension of the Tracer interface.

56

Page 57: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

For more about this Tracer extension, please see Tracer extensions on page 112 .

4.1.3 RhinoSbbContext interface getActivities methods

The RhinoSbbContext interface defines two getActivities methods:

• getActivities() — This method overrides the same method from SbbContext to return a Rhino-specific extension of the

ActivityContextInterface interface. This ActivityContextInterface extension is described in more detail below.

Otherwise, this method behaves in the same way as defined by the JAIN SLEE specification.

• getActivities(Class) — This method behaves similarly to the no-argument version; however it only returns activity context

objects where the type of the underlying activity object is assignable to the class argument. For example, if this method was invoked

with NullActivity.class as an argument, then only activity context objects for the null activities the SBB entity is attached to

would be returned.

4.1.4 RhinoSbbContext interface getChildRelationFacility method

The getChildRelationFacility returns a Child Relation Facility object for the SBB.

For more about the Child Relation Facility, please see Child Relation Facility on page 91 .

4.1.5 RhinoSbbContext interface getCMPFields method

The getCMPFields method provides the SBB with access to its per-instance state.

For details on the CMPFields object returned from this method, please see The CMPFields interface on page 51 .

4.1.6 RhinoSbbContext interface getJndiBindings method

The getJndiBindings method returns a map describing the JNDI bindings available to the SBB.

57

Page 58: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

For more about this method, please see JNDI environment metadata on page 115 .

4.1.7 RhinoSbbContext interface setServiceContext and getServiceContext methods

The setServiceContext and getServiceContext methods allow setting and retrieving the service context object for the SBB. The service

context provides an alternative storage mechanism to using static class fields for arbitrary, typically constant data that the SBB wants to share

between SBB objects in the same service. The use of static class fields to store shared data becomes problematic when the encapsulating class

resides in a library component jar rather than an SBB jar. In this case the static fields end up being shared between all uses of that library, rather

than being scoped to a single service. The service context provides similar functionality to that of a static class field, but it is guaranteed to have

visibility only within the service.

A typical use of the service context is to store data calculated by the SBB during the SBB Service Lifecycle Callbacks on page 64 service

lifecycle callback methods.

Any object may be stored in the service context. The service context object is stored by reference, and is never serialised. As the service context

object may be accessed concurrently by different SBB objects, care must be taken that the service context object provides thread-safe access

where necessary.

A service context object will persist across service deactivation and reactivation cycles unless the SBB explicitly resets the service context to null

at the appropriate time.

The visibility of a service context object is scoped to a single SBB type within a service. All SBB objects of the same SBB type share the same

service context. Different SBB types within the same service may each store their own service context object without conflict.

4.1.8 RhinoSbbContext interface setEncodableContext method

The setEncodableContext method sets the encodable context for the SBB.

For more about encodable contexts, please see Encodable context on page 34 .

58

Page 59: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

4.2 Activity context Suspend/Resume Delivery extensions

The JAIN SLEE specification allows delivery of events to be suspended and resumed using the methods defined in the

javax.slee.EventContext interface. An obvious restriction to this is that suspending event delivery requires an EventContext object, and

the only way to obtain an EventContext object of an unsuspended event is by event handler method argument; therefore an SBB can only

suspend delivery of an event that is being delivered to it. An SBB that attaches to multiple activities may at times desire to suspend delivery of

events on a selected subset of these activities while waiting for the result of some asynchronous action. The SLEE specification does not provide

a trivial solution to this problem, instead requiring a complicated process of suspending events on those activities as they are received, then

resuming and processing those events at an appropriate time in a later transaction.

Rhino simplifies this problem by allowing event delivery on any activity context to be suspended and resumed at any time.

Rhino defines the com.opencloud.rhino.slee.RhinoActivityContextInterface interface, an extension to

javax.slee.ActivityContextInterface , with methods providing this functionality. The RhinoActivityContextInterface interface is

shown below:

package com.opencloud.rhino.slee;

import javax.slee.ActivityContextInterface;import javax.slee.SLEEException;import javax.slee.TransactionRequiredLocalException;

public interface RhinoActivityContextInterface extends ActivityContextInterface { public void suspendDelivery() throws IllegalStateException, TransactionRequiredLocalException, SLEEException;

public void suspendDelivery(int timeout) throws IllegalArgumentException, IllegalStateException, TransactionRequiredLocalException, SLEEException;

public void resumeDelivery() throws IllegalStateException, TransactionRequiredLocalException, SLEEException;

public boolean isSuspended() throws TransactionRequiredLocalException, SLEEException;

59

Page 60: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

}

All activity context objects that Rhino provides to SBBs implement RhinoActivityContextInterface ; therefore a typecast of an activity

ccntext object to this interface will always succeed. Rhino will also recognise an event handler method defined with this type, instead of the

standard ActivityContextInterface , as the second method argument, removing the need to perform a typecast within the method body if

the extensions are required.

An SBB or SBB Part activity context Interface on page 68 may be declared as extending RhinoActivityContextInterface rather than

ActivityContextInterface if desired.

4.2.1 RhinoActivityContextInterface interface suspendDelivery methods

The suspendDelivery methods suspend further delivery of events on the invoked activity context. An activity context is only ever suspended for

a specific period of time. The no-argument variant of this method suspends event delivery until some system specific default timeout is reached,

while the one-argument variant suspends event delivery for a specific timeout period in milliseconds. The timeout period is measured from the time

the suspendDelivery method is invoked. Some time after the timeout period expires, delivery of events on the activity context is automatically

resumed. Event delivery can also be manually resumed by an SBB before the timeout period expires, using the resumeDelivery method.

If an SBB suspends delivery of events on an activity context for which it is currently processing an event, then event delivery of that event is

suspended in the same way as if suspended using the event context associated with the event.

If an SBB suspends delivery of events on an activity context for which it is not currently processing an event, and the SLEE is already

asynchronously delivering an event on that activity context to an SBB, then event delivery suspension of that activity context takes effect after the

event handler method invoked on that SBB returns. If the SLEE is not currently delivering an event on that activity context, then event delivery

suspension takes immediate effect.

These methods are mandatory transactional methods. The delivery of events fired on the activity context is only suspended if the enclosing

transaction commits. If the transaction does not commit, then event delivery will not be suspended.

These methods throw the following exceptions:

Exception When thrown

60

Page 61: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

java.lang.IllegalArgumentException

The timeout argument is zero or a negative value.

javax.slee.IllegalStateException

Event delivery has already been suspended on the activity context, either by a suspendDel

ivery method invocation on the activity context itself or a suspendDelivery method

invocation on an EventContext object associated with an event delivered on the activity

context.

javax.slee.TransactionRequiredLocalException

This method is invoked without a valid transaction context.

javax.slee.SLEEException Event delivery on the activity context could not be suspended due to a system-level failure.

4.2.2 RhinoActivityContextInterface interface resumeDelivery methods

The resumeDelivery method resumes the delivery of events on the invoked activity context.

This method is a mandatory transactional method. The delivery of events occurring on the activity context is only resumed if the enclosing

transaction commits. If the transaction does not commit, then event delivery will not be resumed.

This method throws the following exceptions:

Exception When thrown

javax.slee.IllegalStateException

Delivery of events on the activity context is not currently suspended; for example, if event

delivery has not been suspended or has already been resumed.

javax.slee.TransactionRequiredLocalException

This method is invoked without a valid transaction context.

javax.slee.SLEEException Event delivery on the activity context could not be resumed due to a system-level failure.

61

Page 62: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

4.2.3 RhinoActivityContextInterface interface isSuspended methods

The isSuspended method determines if the delivery of events on the activity context is currently suspended. This method returns true if the

event delivery is suspended or false otherwise.

This method is a mandatory transactional method. This method throws the following exceptions:

Exception When thrown

javax.slee.TransactionRequiredLocalException

This method is invoked without a valid transaction context.

javax.slee.SleeException The event delivery status of the activity context could not be determined due to a system-level

failure.

4.2.4 Relationship to event context suspend/resume

The event delivery status of an event context is linked to the event delivery status of its associated activity context. If an event context is

suspended, then event delivery on the activity context is also suspended, and vice versa. Similarly, if an event context is resumed, then event

delivery on the activity context is also resumed. Therefore, an SBB that wants to suspend delivery of events on an activity context for which it

is currently processing an event may do so in one of two ways — by invoking a suspendDelivery method on either the event context for the

received event or on the activity context that the event was delivered on.

Both these operations have the same effect. Of particular note, after either method has been invoked, both the event context and the activity

context will return true from their respective `isSuspended methods.

An SBB may also resume delivery of events on an activity context in one of two ways — by invoking the resumeDelivery method on either the

event context of the suspended event (if the event context is available) or on the activity context.

Again, both these operations will have the same effect; and after either method has been invoked, both the event context and the activity context

will return false from their respective isSuspended methods.

62

Page 63: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

4.3 SBB local home interface

The JAIN SLEE specification allows an SBB component to declare a local interface. An SBB entity can invoke a target SBB entity in a

synchronous manner through the SBB local interface of the target SBB. Rhino also allows an SBB to declare a local home interface. Methods

invoked on the local home interface are not specific to any SBB entity and are executed by an SBB object in the Pooled state. An SBB local home

object is an instance of a SLEE-implemented class that implements an SBB local home interface.

4.3.1 How to get an SBB local home object

An SBB can only get an SBB local home object for its child SBBs. An SBB can get an SBB local home object for each of its child SBBs using the

Child Relation Facility on page 91 . The getChildSbbLocalHome method defined by the ChildRelationFacility interface returns an

SBB local home object for the specified child SBB relation.

4.3.2 The RhinoSbbLocalHome interface

This interface is the base interface of all SBB local home interfaces. Currently Rhino does not allow an SBB to extend this interface; so all SBB

local home interfaces, if declared, must be declared as this interface. If an SBB does not declare an SBB local home interface, then the SBB local

home interface defaults to RhinoSbbLocalHome .

The RhinoSbbLocalHome interface is shown below:

package com.opencloud.rhino.slee;

import javax.slee.TransactionRequiredLocalException;

public interface RhinoSbbLocalHome { public Object verifyConfiguration() throws InvalidConfigurationException, TransactionRequiredLocalException;

public void serviceActivating(Object config) throws TransactionRequiredLocalException;

public void serviceDeactivating() throws TransactionRequiredLocalException;}

63

Page 64: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

If an SBB declares a local home interface in its deployment descriptor, then the local home interface methods must be implemented in the SBB

abstract class using a method name constructed by capitalising the first letter of the method name as defined in this interface then prefixing

sbbHome . The method parameters and return type must be identical, and the throws clause of the implemented method must be the same as or a

subset of the interface method declaration, excluding any runtime exceptions.

Although an SBB that does not declare an SBB local interface receives RhinoSbbLocalHome as a default local home interface, such an SBB

is not required to implement the local home interface methods in the SBB abstract class. The SLEE will instead provide a default no-operation

implementation of these methods.

4.3.3 SBB service lifecycle callbacks

The RhinoSbbLocalHome interface defines methods that allow an SBB to receive callbacks when a service it is used in is activated or

deactivated. These methods are described below.

4.3.4 RhinoSbbLocalHome interface verifyConfiguration method

The SLEE invokes the verifyConfiguration method on the root SBB of a service when the service is about to transition from Inactive to

Active. This callback can be used by an SBB, for example, to check that its configuration in environment entries or elsewhere is valid. The SBB

can throw an InvalidConfigurationException from this method if a configuration error or other reason means that the service should not

be activated at this time.

Child SBBs in the service may also receive this callback method invocation, as described in the Lifecycle callback method invocation cascade on

page 66 section below.

In Rhino, this method is invoked on a service on each cluster node where the service is about to transition to the Active state.

If an SBB declares a local home interface, then a corresponding method with the following signature must be implemented in the SBB abstract

class:

public Object sbbHomeVerifyConfiguration() throws InvalidConfigurationException;

The throws clause is optional.

• If the method throws an InvalidConfigurationException when the administrator has requested activation of the service on a

node that is currently operational, then the activation request fails and the service state remains unchanged.

64

Page 65: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• If the method throws an InvalidConfigurationException exception when a node (re)starts, where the per-node state for that

node indicates that the service should be reactivated, then the reactivation attempt fails, the service transition back to the Inactive

state on that node, and an alarm is raised to indicate that the service could not be activated.

The return result from this method is passed as an argument to the serviceActivating method if the service successfully activates. This

object can be used, for example, to pass some configuration information calculated during this method to the serviceActivating method if that

method would otherwise need to recalculate the same information again.

This method is a mandatory transactional method. When this method is invoked by the SLEE, it is invoked with an active transaction context. If

this method is invoked by an SBB without a valid transaction context then a TransactionRequiredLocalException is thrown.

4.3.5 RhinoSbbLocalHome interface serviceActivating method

The SLEE invokes the serviceActivating method on the root SBB of a service when the service is about to transition from Inactive to Active.

This method is invoked after the verifyConfiguration method has returned successfully and the SLEE has determined that the service

activation can proceed to completion. The SBB can use this callback, for example, to initialise common state shared between SBB objects (such

as the service context of the same SBB).

Child SBBs in the service may also receive this callback method invocation, as described in the Lifecycle callback method invocation cascade on

page 66 section below.

In Rhino, this method is invoked on a service on each cluster node where the service is about to transition to the Active state. The service

transitions to the Active state on the corresponding node after this method returns.

If an SBB declares a local home interface, then a corresponding method with the following signature must be implemented in the SBB abstract

class:

public void sbbHomeServiceActivating(Object config);

When this method is invoked by the SLEE, the object passed as an argument to this method is the return result from the previous corresponding

verifyConfiguration method invocation.

This method is a mandatory transactional method. When this method is invoked by the SLEE, it is invoked with an active transaction context. If

this method is invoked by an SBB without a valid transaction context then a TransactionRequiredLocalException is thrown.

65

Page 66: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

4.3.6 RhinoSbbLocalHome interface serviceDeactivating method

The SLEE invokes the serviceDeactivating method on the root SBB of a service when no SBB entity trees remain in the service and it is

about to transition from the Stopping state to the Inactive state. An SBB can use this callback, for example, to clean up any shared state that is no

longer required after the service has deactivated.

Child SBBs in the service may also receive this callback method invocation, as described in the Lifecycle callback method invocation cascade on

page 66 section below.

In Rhino, this method is invoked on a service on each cluster node where the service is about to transition to the Inactive state. The service

transitions to the Inactive state on the corresponding node after this method returns.

If an SBB declares a local home interface, then a corresponding method with the following signature must be implemented in the SBB abstract

class:

public void sbbHomeServiceDeactivating();

This method is a mandatory transactional method. When this method is invoked by the SLEE, it is invoked with an active transaction context. If

this method is invoked by an SBB without a valid transaction context, then a TransactionRequiredLocalException is thrown.

4.3.7 Lifecycle callback method invocation cascade

The SBB service lifecycle callback methods are initially invoked by the SLEE on the root SBB of a service. If the root SBB has child SBB relations

where the cascade-service-lifecycle-callbacks option in the SBB extension deployment descriptor is set to True , then the SLEE will

also automatically invoke the same lifecycle callback method on each of those child SBBs. This process repeats or "cascades" to each child SBB

in the service where the cascade-service-lifecycle-callbacks option in the parent SBB requests it. The SLEE however will invoke this

method at most once for each SBB type present in the service, regardless of how many times a given SBB appears as a child SBB in the service.

Lifecycle callback method invocation cascade is enabled by default on all child relations. Cascade may be disabled for a given child SBB relation

by setting the corresponding cascade-service-lifecycle-callbacks option in the SBB extension deployment descriptor to False . As

an alternative to automatic cascade, an SBB can manually invoke the lifecycle callback methods directly on any of its child SBBs by obtaining

the child SBB’s local home object from the Child Relation Facility on page 91 . Lifecycle callback methods invoked by an SBB, rather than the

SLEE, do not cascade to other child SBBs, even if those child SBB relations are flagged for cascade.

66

Page 67: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Lifecycle callback method invocations proceed to cascade through eligible child SBB relations irrespective of whether or not the root SBB or any

given child SBB declares a local home interface. An SBB that does not declare a local home interface is simply unaware that the callback method

invocation occurred.

4.4 Unchecked throwable propagation

The JAIN SLEE specification states that if a method invocation on an SBB or a profile returns by throwing an unchecked exception, then (amongst

other things) the transaction is marked for rollback and a javax.slee.TransactionRolledBackLocalException is propagated back to the

caller. There may be times, however, in certain applications where this behaviour is undesirable, and the caller would rather catch and handle the

exception itself rather than have the transaction forcibly rolled back.

To address this need, Rhino provides the @PropagateUncheckedThrowables annotation. This annotation can be used on any SBB local

interface method or profile local interface method to indicate that any unchecked throwable ( RuntimeException s or Error s) produced by the

method must be propagated back to the caller as-is. The transaction is not marked for rollback, and the invoked SBB or profile object remains in

the same state; in other words, it is not discarded by a transition to the Does Not Exist state.

An SBB local interface or profile local interface class declaration may also be annotated with @PropagateUncheckedThrowables . When used

in this way, the annotation indicates that all methods defined in the interface, and all inherited methods, shall exhibit the behaviour defined by the

annotation, as if all these methods were annotated individually.

The propagation of unchecked throwables only applies to exceptions produced by the invoked method itself. The annotation has no effect

against container-generated exceptions that cause rollback, such as trying to invoke a local interface method on an SBB that no longer

exists. The annotation is also ignored for methods originally defined in the base local interfaces: javax.slee.SbbLocalObject and

javax.slee.profile.ProfileLocalObject .

67

Page 68: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

5 SBB Parts

This page includes these details for using SBB parts:

5.1 What are SBB parts?

An "SBB part", as its name implies, can be thought of as a sub-component of a JAIN SLEE SBB (Service Building Block). An SBB part is an

installable SLEE component in its own right. It may have dependencies, and other components may depend on it. The concept of the SBB part

component was borne from a use case where the developer wanted to put a number of common shared classes into a library-type component;

but the classes had dependencies on various profile specifications, event types, and resource adaptor types — all of which a standard JAIN SLEE

library component cannot provide (a library component may only depend on other library components). We thought it might be desirable to extend

the definition of the standard library component with the option to declare these other types of references, mainly because a library component

was always seen as a passive "primitive" type of component that sat at the top of the dependency hierarchy. Adding dependency links to other

component types would significantly complicate the SLEE component dependency hierarchy. In particular, it would create the possibility of cyclic

dependencies between different component types — which must be avoided, as in practise they cannot be mapped to a realistic runtime class

loader hierarchy. So instead, a new component type was created to fulfill this need: the SBB part.

SBB part components have one other feature that make them distinct from library components: at runtime the SBB part component classes are

included in the same class loader as the SBB classes for the service, rather than in a parent class loader (as standard library components are).

5.2 SBB part components

An SBB part component may define:

• dependencies — on libraries, event types, resource adaptor types, profile specifications and other SBB parts

• per-instance state — held in Container Managed Persistence (CMP) fields that can maintain persistent state that should persist

across failures

• usage statistics — collected through usage parameters interface types declared by the SBB part component (see Usage in the

Rhino Administration and Deployment Guide for a description of Rhino’s usage extension mechanism)

68

Page 69: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• event handler methods — provided by the SBB part component for each event type it receives, with application logic to process

events of a specific event type

• shareable data — defined by the SBB part component to share with other components as a set of activity context attributes (each

activity context attribute has a name and a type, and is stored in one or more activity contexts — an SBB part component defines an

activity context interface interface that provides type-safe accessor methods to get and set these attributes).

An SBB part component can only be referenced by SBB components or other SBB part components.

5.3 SBBs and SBB parts

An SBB may depend on one or more SBB parts. An SBB part may also depend on other SBB parts. An SBB that depends on one or more SBB

parts, both directly and indirectly, has its definition implicitly extended in the following ways:

per-instance state The per-instance persistent state of the SBB is defined by the union of the CMP fields declared by the SBB

and the CMP fields declared by each dependent SBB part. All CMP fields declared by these components

share the same namespace. A CMP field declared by both the SBB and a dependent SBB part, or two

different dependent SBB parts, must be declared with the same field type, as they each refer to the same

piece of per-instance state.

usage statistics The usage parameters interface types available to the SBB is the union of the usage parameters interface

types declared by the SBB and the usage parameters interface types declared by each dependent SBB part.

All usage parameters interface types declared by these components share the same namespace. A usage

parameters interface type declared by both the SBB and a dependent SBB part, or two different dependent

SBB parts, must be declared with the same usage parameters interface class name. Amongst the SBB and

all dependent SBB parts, at most one usage parameters interface type may be declared as the root usage

parameter set type.

event handler methods The event handler methods available to the SBB is the union of the event handler methods defined by the

SBB and the event handler methods defined by each dependent SBB part. Any given event type can have

at most one event handler method defined between the SBB and the SBB parts — if the SBB declares an

69

Page 70: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

event handler method for a given event type, then no dependent SBB part may also declare an event handler

method for the same event type.

shareable data The activity context attributes of the SBB are the union of the activity context attributes declared by the SBB

and the activity context attributes declared by each dependent SBB part. All activity context attributes declared

by these components share the same namespace. An activity context attribute declared by both the SBB and

a dependent SBB part, or two different dependent SBB parts, must be declared with the same type, as they

each refer to the same attribute. The SBB and dependent SBB parts may each declare an alias for the same

activity context attribute, but the alias name must be identical; in other words, each alias declaration must be

identical. If any of the components declare an alias for a given activity context attribute, then the alias applies

to all the components.

JNDI environment The JNDI bindings available to the SBB is the union of all JNDI bindings declared by the SBB and all JNDI

bindings declared by each SBB part. A binding to a given name declared by both the SBB and a dependent

SBB part, or two different dependent SBB parts, must be declared with the same value. For example, if the

binding is made to a resource adaptor entity, then each binding declaration must have the same resource

adaptor type reference.

Put simply, an SBB becomes the union of the declarations made by itself and all its dependent SBB parts; and there must be no conflict between

components that make the same declarations.

5.4 SBB part objects

An SBB part may optionally declare an SBB part class on page 73 . The SBB part class contains the event-processing logic of the SBB part

component. An instance of the SBB part class is known as an SBB part object.

The lifecycle of an SBB part object is tightly coupled to the lifecycle of an SBB object. When an SBB object is created, an SBB part object for each

dependent SBB part that declares an SBB part class is also created; and the SBB object maintains a reference to this SBB part object for the

lifetime of the SBB object. When the SBB object undergoes a lifecycle state transition, for example from the Pooled state to the Ready state, each

dependent SBB part object also undergoes the same lifecycle transition. If the SLEE determines that the SBB object is no longer required and

becomes eligible for JVM garbage collection, then so too do the dependent SBB part objects.

70

Page 71: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

During the lifetime of an SBB part object, it may be assigned to different SBB entities. When the SBB part object is assigned to an SBB part entity,

it can receive events destined for the SBB entity and can manipulate the persistent state of the SBB entity. It can also access the relationships of

the SBB entity.

5.4.1 SBB part object lifecycle

An SBB part object can be in one of the following three states:

• Does Not Exist — The SBB part object does not exist. It may not have been created or it may have been deleted.

• Pooled — The SBB part object exists but is not assigned to any particular SBB entity.

• Ready — The SBB part object is assigned to an SBB entity. It is ready to receive events through its event handler methods.

The following steps describe the lifecycle of an SBB part object:

1. An SBB part object’s lifecycle starts when the SLEE creates the object using newInstance . The SLEE passes the SBB part object

an SbbPartContext on page 86 object to the constructor if the constructor defines such an argument. The SbbPartContext

object allows the SBB part object to invoke functions provided by the SLEE. Once the SBB object is created, the SLEE then injects

values into SBB part class fields annotated for dependency injection.

2. The SBB part object is bound to an owning SBB object. While the SBB object is in the Pooled state, the SBB part object is also in the

Pooled state, and is not associated with any particular SBB entity.

3. An SBB part object transitions from the Pooled state to the Ready state when the SLEE selects the owning SBB object to process an

event or to service a logic object invocation. There are two possible transitions from the Pooled state to the Ready state: through the

@PostCreate method, or through the @OnActivate method.

• The SLEE invokes the @PostCreate method when the SBB part object is assigned to a new SBB entity that has just been

created explicitly by an invocation of the create method on a ChildRelation object, or implicitly by the SLEE to process an

initial event.

• The SLEE invokes the @OnActivate method on an SBB part object when the owning SBB object needs to be activated to

receive a method invocation on an existing SBB entity. This occurs when there is no existing SBB object in the Ready state

assigned to the SBB entity available to receive the invocation.

4. When an SBB part object is in the Ready state, the SBB part object is associated with a specific SBB entity. While the SBB part

object is in the Ready state, the SLEE can synchronise the transient state held in the SBB part object with the persistent state of the

71

Page 72: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

SBB entity whenever it determines the need to, by invoking the @PostLoad and @PreStore methods zero or more times. Event

handler and exception callback methods can be invoked on the SBB part object zero or more times. Invocations of the @PostLoad

and @PreStore methods can be arbitrarily mixed with invocations of these methods subject to the SBB part object lifecycle.

5. The SLEE can choose to passivate an SBB object. Passivating an SBB object disassociates the SBB object from the SBB entity

it is currently assigned to. When an SBB object is passivated, its dependent SBB part objects are also passivated and therefore

disassociated from the SBB entity. When an SBB part object is passivated, the SLEE first invokes the @PreStore method to allow

the SBB part object to prepare itself for the synchronisation of the SBB entity’s persistent state with the SBB part object’s transient

state; then the SLEE invokes the @OnPassivate method to return the SBB part object to the Pooled state.

6. Eventually, the SLEE will transition the SBB part object to the Pooled state. There are two possible normal transitions from the Ready

state to the Pooled state: through the @OnPassivate method, and through the @PreRemove method.

• The SLEE invokes the @OnPassivate method when the SLEE wants to disassociate the SBB object and its dependent SBB

part objects from the SBB entity without removing the SBB entity.

• The SLEE invokes the @PreRemove method when the SLEE wants to remove the SBB entity (in other words, when the SBB

entity is removed as part of cascading removal of an SBB entity sub-tree).

7. When the SBB object and its dependent SBB part objects are put back into the pool, they are no longer associated with the SBB

entity. The SLEE can assign the SBB object and SBB part objects to any SBB entity of the same SBB component.

8. The SLEE may release its references to an SBB object in the pool, along with its dependent SBB part objects, allowing them to be

garbage collected. It may do this after calling the unsetSbbContext method on the SBB object, and the @PreDispose method on

each SBB part object.

• The SbbPartContext object passed by the SLEE to the SBB part object in the constructor, or by dependency

injection, is not an object that contains static information. For example, the result of the getSbbLocalObject method

might be different each time an SBB part object moves from the Pooled state to the Ready state, and the result of the

getActivities method may be different in different event handler method invocations.• An SBB part object is only ever associated with one SBB in one service. This means that the getService , getSbb ,

and getSbbPart methods of an SbbPartContext object always return the same result during the lifetime of the SBB

part object.

72

Page 73: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• The order in which the SLEE invokes dependent SBB part objects for a given lifecycle callback method is not defined.

The SBB part objects may be invoked in any order; however the SBB part object callbacks will always be made before

or after the corresponding SBB object lifecycle callback method invocation, as defined in the Lifecycle methods on page

73 section.• A RuntimeException thrown from any method of an SBB part object (including the event handler methods and

the lifecycle callbacks invoked by the SLEE) results in the transition to the Does Not Exist state after the appropriate

exception handler methods have been invoked. The SLEE will not invoke any method except the @OnException method

on the SBB part object after a RuntimeException has been caught. The corresponding SBB entity continues to exist.

The SBB entity can continue to receive events and synchronous invocations because the SLEE can use different SBB

and SBB part objects to process events and synchronous invocations that should be sent to the SBB entity. For more on

exception handling, see the Exception callback method on page 81 section.

5.5 SBB part class

An SBB part must define an SBB part class if the SBB part declares event handler methods. In any other case, the definition of an SBB part class

is optional. An SBB part class must:

• be defined in a named package; that is, the class must have a package declaration

• be defined as public

• not be abstract or final

• not define the finalize method.

The SBB developer implements the SBB part class. In it, they may define lifecycle and event handler methods, and an exception callback. The

SBB part class may also use Dependency Injection on page 83 for various types of fields.

5.5.1 Lifecycle methods

Each SBB part object has a lifecycle. The SLEE invokes the lifecycle methods of the SBB part object to make the SBB part object aware of its

lifecycle state. The SLEE invokes a given lifecycle method on an SBB part object at the same time that it invokes the corresponding lifecycle

method on the owning SBB object; however the order in which different dependent SBB parts are invoked for a given lifecycle method invocation

is not defined.

73

Page 74: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

The lifecycle methods are described below. In the case of lifecycle methods denoted by annotations, at most one of each lifecycle method may be

declared in an SBB part class.

Constructor

The SBB part class must define a public constructor that takes either no arguments or a single argument of type

com.opencloud.rhino.slee.sbbpart.SbbPartContext on page 86 . The SLEE invokes the constructor of an SBB part class to create a new SBB

part object. The SLEE creates a new SBB part object when the owning SBB object transitions from the Does Not Exist state to the Pooled state.

If the SBB part object needs to use the SbbPartContext object during its lifetime, it should keep a reference to the SbbPartContext object in an

instance variable. Alternatively, the SBB part object may obtain a reference to an SbbPartContext object using Dependency Injection on page

83 .

During the constructor invocation, the SBB part object is not assigned an SBB entity. The SBB part object can use the constructor to allocate and

initialise state or connect to resources that are to be held by the SBB part object during its lifetime. Such state and resources cannot be specific to

an SBB entity, because the SBB part object might be reused during its lifetime to service multiple SBB entities.

The SBB part object constructor invocation corresponds to the setSbbContext lifecycle method of the SBB abstract class, and is invoked after

the setSbbContext method returns successfully.

If both supported constructors are defined, then the one-argument constructor is used.

• The SBB part class constructor must not define a throws clause.• The SBB part object must not attempt to access its persistent state using the CMP field accessor methods during the

constructor invocation.• The constructor is invoked with an unspecified transaction context.

@PreDispose

The SBB part class may optionally implement a lifecycle callback method invoked by the SLEE before the SLEE terminates the life of the SBB part

object. This method must be annotated with the @PreDispose annotation. This method is invoked when the SBB part object transitions from the

Pooled state to the Does Not Exist state. During this method, an SBB entity is not assigned to the SBB part object. The SBB part object can use

this method to free state or resources that are held by the SBB part object. These state and resources typically had been allocated by the SBB

part class constructor.

74

Page 75: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

This method corresponds to the unsetSbbContext lifecycle method of the SBB abstract class, and is invoked before the unsetSbbContext

method is invoked on the owning SBB object.

• A method annotated with @PreDispose method must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments, must have a void return type, and must not define a throws clause.• The SBB part object must not attempt to access its persistent state using the CMP field accessor methods during this

method.• This method is invoked with an unspecified transaction context.

@PostCreate

The SBB part class may optionally implement a lifecycle callback method invoked when a new SBB entity is created. The method must be

annotated with the @PostCreate annotation. This method is invoked when the SBB part object transitions from the Pooled state to the Ready

state as a result of SBB entity creation, and is invoked after the persistent representation of the SBB entity has been created and the SBB part

object is assigned to the created SBB entity. This method can be used to initialise any transient state and acquire any resources that the SBB part

needs while it is in the Ready state.

• A method annotated with @PostCreate must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments and must have a void return type.• This method may throw a javax.slee.CreateException when there is an application level problem (rather than

a SLEE or system level problem). The SLEE will also propagate the CreateException unchanged to the caller that

requested the creation of the SBB entity. The caller may be the SLEE or an SBB object. The throws clause is optional.• This method may not define a throws clause that includes any exception other than CreateException .• The SLEE guarantees that the values that will be initially returned from the getter methods of any CMP field declared

exclusively by the SBB part will be the Java language defaults (such as 0 for integer, or null for object references),

unless those CMP fields have been annotated with CMP Field Enhancements on page 25 @InitialValueFields on page 42

, in which case the initial value returned by the CMP field getter method will be as defined by the initial value field.• The SLEE invokes this method with the transaction context used to invoke the sbbCreate and sbbPostCreate

methods on the owning SBB object.

75

Page 76: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• The SBB part object enters the Ready state after this method returns normally. If this method returns by throwing an

exception, the SBB part object does not become Ready.

This method corresponds to the sbbPostCreate lifecycle method of the SBB abstract class, and is invoked after the sbbPostCreate method

returns successfully.

Note that there is no SBB part lifecycle method equivalent to the SBB abstract class sbbCreate method.

@OnActivate

The SBB part class may optionally implement a lifecycle callback method invoked when the SLEE needs to assign an SBB part object in the

Pooled state to a existing SBB entity. This method must be annotated with the @OnActivate annotation. The SBB part object transitions to the

Ready state after this method returns. This method gives the SBB part object a chance to initialise additional transient state and acquire additional

resources that it needs while it is in the Ready state.

• A method annotated with @OnActivate must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments, must have a void return type, and must not define a throws clause.• The SBB part object must not attempt to access its persistent state using the CMP field accessor methods during this

method.• This method executes with an unspecified transaction context.

This method corresponds to the sbbActivate lifecycle method of the SBB abstract class, and is invoked after the sbbActivate method returns

successfully.

@OnPassivate

The SBB part class may optionally implement a lifecycle callback method invoked when the SLEE decides to disassociate an SBB part object

in the Ready state from the SBB entity it is currently associated with. This method must be annotated with the @OnPassivate annotation. The

SBB part object transitions to the Pooled state after this method returns. This method gives the SBB part object the change to release any state or

resources that should not be held while the SBB part object is in the Pooled state. These state and resources typically had been allocated during

the @OnActivate method.

76

Page 77: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• A method annotated with @OnPassivate must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments, must have a void return type, and must not define a throws clause.• The SBB part object must not attempt to access its persistent state using the CMP field accessor methods during this

method.• This method executes with an unspecified transaction context.

This method corresponds to the sbbPassivate lifecycle method of the SBB abstract class, and is invoked after the sbbPassivate method

returns successfully.

@PreRemove

The SBB part class may optionally implement a lifecycle callback method invoked by the SLEE when the SBB entity assigned to the SBB part

object is about to be removed. This method must be annotated with the @PreRemove annotation. The SBB part object is in the Ready state when

this method is invoked, and it will transition to the Pooled state after this method returns. This method can be used to implement any actions that

must be done before the SBB entity’s persistent representation is removed.

• A method annotated with @PreRemove must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments, must have a void return type, and must not define a throws clause.• The SLEE synchronises the SBB part object’s state before it invokes the @PreRemove method. This means that the

CMP state of the SBB part object at the beginning of this method is the same as it would be at the beginning of an event

handler method.• This method is invoked with same transaction context as used to invoke the sbbRemove method on the owning SBB

object.• Since the SBB part object will transition to the Pooled state, the state of the SBB part object at the end of this method

must be equivalent to the state of a passivated SBB part object. This means that the SBB part object must free any state

and release any resource that it would normally release in the @OnPassivate method (if declared).

This method corresponds to the sbbRemove lifecycle method of the SBB abstract class, and is invoked before the sbbRemove method is invoked

on this owning SBB object.

77

Page 78: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

@PostLoad

The SBB part class may optionally implement a lifecycle callback method invoked by the SLEE to synchronise the state of the SBB part object with

its assigned SBB entity’s persistent state. This method must be annotated with the @PostLoad annotation. The SBB developer can assume that

the persistent state of the SBB entity the SBB part object is assigned to has been loaded just before this method is invoked. It is the responsibility

of the SBB developer to use this method to re-compute or initialise the values of any transient instance variables in the SBB part object that

depend on the SBB entity’s persistent state. In general, any transient state that depends on the persistent state of an SBB entity should be

recalculated in this method. The SBB developer can use this method, for instance, to perform some computation on the values returned by the

CMP field accessor methods, such as converting text fields to more convenient objects or binary representations.

• A method annotated with @PostLoad must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments, must have a void return type, and must not define a throws clause.• The SLEE invokes this method within a transaction context.

This method corresponds to the sbbLoad lifecycle method of the SBB abstract class, and is invoked after the sbbLoad method returns

successfully.

@PreStore

The SBB part class may optionally implement a lifecycle callback method invoked by the SLEE to synchronise the SBB entity’s persistent state

with the state of the SBB part object. This method must be annotated with the @PreStore annotation. The SBB developer should use this method

to update the SBB entity using the CMP field accessor methods before its persistent state is synchronised. For example, this method may perform

conversion of object or binary data representations to text. The SBB developer can assume that after this method returns, the persistent state is

synchronised.

• A method annotated with @PreStore must be declared as public and cannot be static, abstract, or final.• This method must not take any arguments, must have a void return type, and must not define a throws clause.• The SLEE invokes this method within a transaction context.

This method corresponds to the sbbStore lifecycle method of the SBB abstract class, and is invoked after the sbbStore method returns

successfully.

78

Page 79: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

5.5.2 Event handler methods

An SBB part class may receive an event through one of its event handler methods. An SBB part declares event handler methods in the same way

as an SBB. For each event type received by the SBB part, you must:

• provide an event element in the SBB part’s sbb-part deployment descriptor element — the value of the event-direction

attribute of the event element must be Receive . It must also include an event-name element and an event-type-ref element.

• The event-name element provides the SBB part scoped name used within the SBB part class to identify the event type, and

determines the name of the event handler method.

• The event-type-ref element references an event-definition element that provides the event type and the event

class.

• The event-definition element is provided and defined by the event producer of the event type.

• The initial-event attribute of the event element may optionally be set to True .

• The event element may optionally include an event-resource-option element.

• implement the event handler method in the SBB part class — this method contains the application logic that will be invoked to process

events of this event type.

The name of the event handler method is derived from the event name of the event type that will be received by the event handler method.

The method name of the event handler method is derived by adding an on prefix to the event name. The event handler method has one of the

following method signatures:

public void on<event name>(<event class> event, <SBB Part Activity Context Interface interface> activity);public void on<event name>(<event class> event, <SBB Part Activity Context Interface interface> activity, EventContext eventContext);

• The first method signature without an event context argument is used if the SBB does not need access to event context.• The second method signature provides access to the event context associated with the event.• An SBB part can only have one event handler method for each event type.• The event handler method must be declared as public and cannot be static, abstract, or final.

79

Page 80: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• The event handler method is a mandatory transactional method. Hence, the SLEE always invokes this method within a

transaction.• An SBB part object as an event consumer receives an event on an activity context. This activity context is the activity

context on which the event was fired. In the case of an event handler method, an SBB part activity context interface

object (if the SBB part defines an SBB part activity context interface interface) or a generic activity context interface object

represents the activity context on which the event was fired.• An event context is associated with the event that is fired if the SBB part implements an event handler method that

includes an event context argument. The event context can be used to suspend and resume further event processing of

this event.• The event handler method may return inadvertently by throwing a RuntimeException . See RuntimeException

handling for transactional methods on page 82 for details on how the SLEE handles this situation.

Event handler methods declared by SBB parts have the same rules and restrictions as event handler methods declared by SBBs.

An SBB part can manage the event types that it may receive for a particular activity context which it is attached to, by altering the event mask as

an SBB would. The maskEvent and getEventMask methods defined in the SbbPartContext interface behave identically to the same methods

defined in the SbbContext interface. An individual SBB or SBB part may only mask the events that it receives. For example, an SBB cannot

mask an event received by a dependent SBB part.

5.5.3 Initial event selector methods

An SBB part class may define an initial event selector method for any event declared as an initial event. The behaviour and function of an initial

event selector declared by an SBB part is identical to the behaviour and function of an initial event selector method declared by an SBB. The

method signature of the initial event selector method is as follows:

public InitialEventSelector <initial event selector method name>(InitialEventSelector ies);

• The initial event selector method must be declared as public and cannot be static, abstract, or final.• The method name is declared in the SBB part deployment descriptor. The method name must not begin with sbbPart ,

and must be a valid Java identifier.• This method is a non-transactional method.

80

Page 81: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• It is only invoked on SBB part objects in the Pooled state.

5.5.4 Exception callback method

The SBB part class may optionally implement a callback method invoked by the SLEE to handle RuntimeExceptions thrown by the SBB

part’s event handler methods and the mandatory transactional lifecycle callback methods: @PostCreate , @PreRemove , @PostLoad , and

@PreStore . This method must be annotated with the @OnException annotation.

• A method annotated with @PreStore must be declared as public and cannot be static, abstract, or final.• This method must declare three arguments in the following order:

1. an Exception argument — this is the exception thrown by one of the methods invoked by the SLEE, such as an

event handler method or a lifecycle method.2. an Object argument — this is the event argument passed to the event handler method, if the exception was

thrown by an event handler method. If the exception was not thrown by an event handler method, this argument

is null .3. an ActivityContextInterface argument — this is the ActivityContextInterface argument passed

to the event handler method, if the exception was thrown by an event handler method. If the exception was

not thrown by an event handler method, this argument is null . The specific type of this argument may be

any subclass of ActivityContextInterface that is assignable to the SBB part’s declared activity context

interface type.• The method must have a void return type, and must not define a throws clause.• This method is a mandatory transactional method.• The SLEE does not invoke this method if a non-transactional method invocation returns by throwing a RuntimeExc

eption .• If this method is invoked on an SBB part object in the Ready state, the state of the SBB part object remains as it was

at the point that the RuntimeException was thrown. The SBB part object moves to the Does Not Exist state after the

@OnException method has been invoked.

81

Page 82: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

A well-written SBB part should not throw any RuntimeExceptions from any of its SLEE invoked methods. Instead, the SBB partshould place the exception handling logic inside a try { } catch (Throwable) clause and handle RuntimeExceptions withineach invoked method.

RuntimeException handling for transactional methods

When a SLEE originated mandatory transactional method is invoked on an SBB part object and the invocation returns with a RuntimeException

thrown, the SLEE performs the following actions:

• The SLEE logs this condition.

• The SLEE marks the transaction of the invocation for rollback.

• The SLEE invokes the @OnException method, if declared, of the same SBB part object with the same transaction. The SBB part

object may be in the Pooled state or in the Ready state. For example, if a @PostCreate method throws the RuntimeException

, then the SBB part object remains in the Pooled state when the SLEE invokes the @OnException method on the SBB part object.

If an event handler method throws the RuntimeException , then the SBB part object remains in the Ready state when the SLEE

invokes the @OnException method on the SBB part object.

• The SLEE moves the SBB part object, along with the owning SBB object and any other dependent SBB part objects, to the Does Not

Exist state.

• If the @OnException method of the SBB part object returns with another RuntimeException thrown, the SLEE logs this condition.

The @OnException method is not reinvoked in this case.

RuntimeException handling for non-transactional methods

When the SLEE invokes a non-transactional method of an SBB part object and the invocation returns by throwing a RuntimeException , the

SLEE performs following sequence of actions:

• The SLEE logs this occurrence.

• The SLEE moves the SBB part object, along with the owning SBB object any other dependent SBB part objects, to the Does Not

Exist state.

82

Page 83: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

5.5.5 Transaction rollback processing

An SBB part object is not involved with transaction rollback processing. If transaction rollback occurs after the SLEE invokes a mandatory

transactional method on an SBB part object, such as an event handler method, the sbbRolledBack callback method will be invoked on an SBB

object of the SBB part’s owning SBB in accordance with the normal SLEE rules for rollback processing.

5.5.6 Method name restrictions

Non-private (such as public, protected, or package private) methods that are defined in an SBB part class must not begin with sbbPart .

5.5.7 Dependency injection

When implementing an SBB part class, the SBB developer has the option to use dependency injection to initialise the value of certain types of

class fields. Dependency injection eliminates the need for the typical boilerplate code associated with the initialisation of these fields.

Dependency injection is supported using the API provided by JSR 330 Dependency Injection for Java , in particular the @javax.inject.Inject

and @javax.inject.Named annotations. Any SBB part class field where dependency injection is required must be annotated with @Inject .

The @Named annotation may also be used, where permitted, to provide an additional parameter to the injector.

The @Inject annotation may be used on SBB part class fields of the following types:

• com.opencloud.rhino.slee.sbbpart.SbbPartContext

• com.opencloud.rhino.cmp.CMPFields , and any type that can be assigned any CMP Extension Interface on page 47 defined

by the SBB part

• javax.slee.facilities.Tracer or com.opencloud.rhino.facilities.Tracer

• The @Named annotation may be used to specify the name of the tracer to assign to the field. The named value must be a valid

SLEE tracer name.

• javax.slee.facilities.ActivityContextNamingFacility

• javax.slee.facilities.AlarmFacility

• javax.slee.facilities.TimerFacility

• javax.slee.profile.ProfileFacility or com.opencloud.rhino.facilities.profile.ProfileFacility

• com.opencloud.rhino.facilities.childrelations.ChildRelationFacility

• com.opencloud.rhino.facilities.usage.UsageFacility

83

Page 84: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• The UsageFacility is only available to SBB parts that declare at least one usage parameters interface.

• If the SBB part declares a root usage parameter set type, then any type that can be assigned the usage parameters interface

of the root usage parameter set type.

• This field will be assigned the root usage parameter set for the SBB part.

• com.opencloud.rhino.license.LicenseFacility

• javax.slee.profile.ProfileTableActivityContextInterfaceFactory

• javax.slee.nullactivity.NullActivityFactory

• The @Named annotation may be used to indicate the specific type of null activity factory to assign to the field. The named

value must be one of replicated , non-replicated , or the empty string . The empty string results in the default null

activity factory for the service to be used, and is equivalent to omitting the @Named annotation.

• javax.slee.nullactivity.NullActivityContextInterfaceFactory

• javax.slee.serviceactivity.ServiceActivityFactory

• javax.slee.serviceactivity.ServiceActivityContextInterfaceFactory

An injected field must not be static or final. Any access modifier (public, protected, package private, or private) is permitted.

If an SBB part class makes use of dependency injection, the SLEE injects these references after the SBB part object is created; in other words,

after the constructor invocation has returned, and before any other methods are invoked on the object. Fields are injected beginning with the

topmost superclass that requests injection, then working down through each subclass as required.

5.5.8 SBB abstract class abstract method replacements

The SBB abstract class allows the declaration of abstract methods in order to provide various functionality to the SBB code. Since the SBB part

class cannot be abstract, alternative mechanisms are provided so that the same functionality is available to SBB parts. These mechanisms are

described below.

Per-instance state

An SBB declares its per-instance state by defining abstract getter and setter methods in the SBB abstract class and indicating that they relate

to CMP fields using <cmp-field> entries in the SBB deployment descriptor. Rhino also allows an SBB to declare CMP fields using CMP

extension interfaces on page . An SBB part can also define its per-instance state using CMP extension interfaces. The SBB part obtains

84

Page 85: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

access to the CMP fields defined in CMP extension interfaces using a com.opencloud.rhino.cmp.CMPFields object, obtainable from its

SbbPartContext object. The CMPFields object may be typecast to any CMP extension interface declared by the SBB part, thus exposing the

CMP field accessor methods defined by the interface.

Activity context interface narrow method

An SBB that declares an activity context interface that is a subtype of javax.slee.ActivityContextInterface is expected to

define an abstract activity context interface narrow method in the SBB abstract class. This method converts or "narrows" a generic

javax.slee.ActivityContextInterface object to an object implementing the SBB’s activity context interface. An SBB part that

declares an activity context interface that is a subtype of javax.slee.ActivityContextInterface can similarly narrow a generic

javax.slee.ActivityContextInterface object using the asSbbPartActivityContextInterface method on its SbbPartContext

object. This method returns an activity context interface object that implements the SBB part’s declared activity context interface.

Child relations

For each child relation that an SBB has, an abstract child relation accessor method must be declared in the SBB abstract class. This method

returns a javax.slee.ChildRelation object that allows child SBBs to be created, inspected, and removed.

As SBB parts cannot declare their own SBB child relations, SBB parts do not need to define child relation accessor methods.

Profile CMP interface accessor method

The profile CMP interface accessor method was deprecated in the JAIN SLEE 1.1 specification. As a replacement, SBBs can use the profile

facility and ProfileTable objects to query and access profiles.

There is no equivalent to the profile CMP interface accessor method for SBB parts. Like SBBs, SBB parts can use the profile facility to query and

access profiles.

Usage parameters interface accessor methods

An SBB that declares a usage parameters interface is expected to declare at least one abstract usage parameters interface accessor method in

the SBB abstract class. This method returns an object implementing the SBB’s usage parameters interface allowing usage statistics for the SBB to

be accumulated.

Rhino provides an extension mechanism on page 94 that allows an SBB to declare more than one usage parameters interface, and defines

a usage facility with which SBBs can manage and access their usage parameter sets. the usage facility eliminates the need for an SBB to

85

Page 86: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

declare the usage parameters interface accessor methods. An SBB part may also declare usage parameters interfaces using the same extension

mechanism, and also may manage and access the SBB’s usage parameter sets using the usage facility.

Fire event methods

If an SBB needs to fire an event as part of its application logic, it must declare an abstract fire event method to do so. Event firing is not supported

for SBB parts, so an SBB part has no equivalent to a fire event method.

5.6 SbbPartContext interface

The SLEE provides each SBB part object, if requested through an SBB part class constructor argument or dependency injection, with an

SbbPartContext object. The SbbPartContext object gives the SBB part object access to the SBB part object’s context maintained by the

SLEE, allows the SBB part object to invoke functions provided by the SLEE, and obtains information about the SBB entity assigned to the SBB

part object.

An SbbPartContext object is associated with one service and one SBB; and the associated service and SBB do not change during the lifetime

of that SbbPartContext object.

The SbbPartContext object implements the SbbPartContext interface. The SbbPartContext interface extends the JAIN SLEE defined

SbbContext interface with additional functionality, as described below.

5.6.1 Methods inherited from SbbContext

The methods inherited from the JAIN SLEE defined SbbContext interface have the same meaning and purpose when used by SBB parts.

5.6.2 SbbPartContext interface getSbbPart method

The getSbbPart method returns an SbbPartID object that encapsulates the component identity of the SBB part.

5.6.3 SbbPartContext interface getTracer method

The getTracer method overrides the same method from SbbContext to return a Rhino-specific extension of the Tracer interface.

86

Page 87: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

For more about this Tracer extension, please see SLEE Facilities on page 90 .

5.6.4 SbbPartContext interface asSbbPartActivityContextInterface method

The asSbbPartActivityContextInterface method is used by the SBB part to narrow an object that implements the generic

ActivityContextInterface to an object that implements the SBB part activity context interface so that the SBB part can access the activity

context interface attributes defined in the SBB part activity context interface.

This method takes as its input parameter an activity context interface object and returns an object that implements the SBB part activity context

interface interface of the SBB part. The SBB part activity context interface interface provides the accessor methods that allow an SBB part object

to access the shareable attributes of the SBB part that are stored in the activity context interface.

If the SBB part does not define an SBB part activity context interface interface, then this method returns the same object passed in as a

parameter.

5.6.5 SbbPartContext interface getActivities methods

The SbbPartContext interface defines two getActivities methods:

• getActivities() — This method overrides the same method from SbbContext to return a Rhino-specific extension of

the ActivityContextInterface interface. Otherwise, this method behaves in the same way as defined by the JAIN SLEE

specification for SBBs.

For more about this ActivityContextInterface extension, please see Miscellaneous SLEE API Enhancements on page 55 .

• getActivities(Class) — This method behaves similarly to the no-argument version; however it only returns activity context

interface objects where the type of the underlying activity object is assignable to the class argument. For example, if this method was

invoked with NullActivity.class as an argument, then only activity context interface objects for the null activities the SBB entity

currently associated with the SBB part is attached to would be returned.

87

Page 88: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

5.6.6 SbbPartContext interface getConvergenceName method

The getConvergenceName method returns the convergence name that the SBB entity the SBB part is associated with was created with. The

value returned from this method is a vendor-specific string that uniquely identifies the initial event selector conditions that led to the SBB entity’s

creation.

This method only returns a non- null value if invoked on an SbbPartContext object belonging to a root SBB entity.

5.6.7 SbbPartContext interface getCMPFields method

The getCMPFields method provides the SBB part with access to its per-instance state on page 84 .

5.6.8 SbbPartContext interface getJndiBindings method

The getJndiBindings method returns a map describing the JNDI bindings available to the SBB part.

For more about this method, please see SLEE Facilities on page 90 .

5.7 SBB part component environment

An SBB part has access to the same JNDI environment bindings as its owning SBB. All the SLEE facilities, environment entries, and resource

adaptor type bindings that are available to an SBB are also available to all its dependent SBB parts. An SBB part accesses its JNDI environment

in exactly the same way as an SBB.

The current specification of SBB parts does not yet allow an SBB part component to declare its own environment entries. An SBB part component

may however define its own resource adaptor type bindings.

5.8 SBB part example

Below is an example of an SBB part class. The SBB part declares an event handler method that receives a SLEE timer event, which logs the

event and increments a CMP field and a usage counter:

import javax.inject.Inject;

88

Page 89: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import javax.inject.Named;import javax.slee.CreateException;import javax.slee.facilities.TimerEvent;import com.opencloud.rhino.facilities.Tracer;import com.opencloud.rhino.slee.lifecycle.PostCreate;

public class ExampleSbbPart {public void onCreate() throws CreateException {rootTracer.info("SBB part created");}

public void onTimerEvent(TimerEvent event, ExampleSbbPartActivityContextInterface aci) {int count = cmpFields.getCounter() + 1;

timerTracer.info("received timer event: " + count);

cmpFields.setCounter(count);

rootUsage.incrementTimerEvents(1);

...}

private Tracer rootTracer;

@Inject @Named("timer")private Tracer timerTracer;

private ExampleSbbPartCMPInterface cmpFields;

private ExampleSbbPartUsageInterface rootUsage;}

89

Page 90: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6 SLEE Facilities

Rhino provides many extensions to the standard facilities and application functions provided by the JAIN SLEE specification, as detailed below.

6.1 SBB child relations

The JAIN SLEE specification defines that an SBB child relation requires:

• an abstract get child relation method declared in the SBB abstract class; and

• a <get-child-relation-method> deployment descriptor entry that binds the get child relation method to a particular SBB type.

The get child relation method returns a ChildRelation object, which the SBB developer uses to create, remove, or manage the SBBs in the

child relation.

A difficulty with this approach is that child relations cannot be added to an SBB without code changes to the SBB abstract class. For example,

consider an SBB that delegates call processing to different child SBBs based on the protocol in use for the call (CAPv2, CAPv3, ETSI INAP CS1,

and so on). Since the child SBB for each protocol needs its own get child relation method in the SBB abstract class, it’s not easy to decide at build

time what protocols will be supported without modifying the SBB abstract class and recompiling. Code changes are also extremely undesirable

when service bindings on page 21 are used to change the child relationships of the SBB after the SBB has been installed in the SLEE.

Rhino provides an alternative mechanism to declare and use SBB child relations, which eliminates the recompilation part of the build cycle in

these types of use cases. Child relations are still declared in the deployment descriptor, but the SBB accesses the child relations using a Child

Relation Facility provided by the SLEE.

6.1.1 Extended child relation declarations

Rhino allows an SBB to declare a child relation with an extension deployment descriptor entry only; in other words, no corresponding get child

relation method is needed in the SBB abstract class. As such, these child relations are termed "declarative" child relations, to differentiate them

from the standard child relations defined by the SLEE specification. Declarative child relations may be added to or removed from an SBB without

the need to recompile any code.

90

Page 91: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Declarative child relations are declared in the oc-sbb-jar.xml extension deployment descriptor using the <child-relations> element. The

child-relations element contains a child-relation element that defines each declarative child relation. A child-relation element

contains the following sub-elements:

Sub-element What it does

description Provides information ( optional ).

child-relation-name Defines the name of the declarative child relation. The SBB uses this name with the Child Relation Facility to

access the child relation. This name must be unique within the scope of the SBB’s declarative child relations.

sbb-alias-ref References an SBB by its sbb-alias that is specified within the corresponding sbb element in the standard

sbb-jar.xml deployment descriptor. This element defines the type of the child SBB.

default-priority Specifies the default event delivery priority of the child SBB relative to its sibling SBBs.

6.1.2 Child Relation Facility

The Child Relation Facility is a Rhino extension that is used by SBBs to gain access to their declarative child relations. The Child Relation Facility

bypasses the need for the SBB developer to declare a get child relation method in the SBB abstract class for each child SBB that the SBB desires.

ChildRelationFacility interface

SBB objects access the Child Relation Facility through a ChildRelationFacility object that implements the ChildRelationFacility

interface. A ChildRelationFacility object can be obtained from the SBB’s RhinoSbbContext on page 55 object (an extension of the standard

SbbContext object).

The ChildRelationFacility interface is as follows:

package com.opencloud.rhino.facilities.childrelations;

import java.util.Collection;import javax.slee.ChildRelation;import javax.slee.SbbLocalObject;

91

Page 92: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import javax.slee.TransactionRequiredLocalException;import javax.slee.facilities.FacilityException;import com.opencloud.rhino.slee.RhinoSbbContext;import com.opencloud.rhino.slee.RhinoSbbLocalHome;

public interface ChildRelationFacility { public Collection<String> getChildRelationNames() throws FacilityException;

public ChildRelation getChildRelation(String name) throws NullPointerException, TransactionRequiredLocalException, IllegalStateException, UnrecognizedChildRelationException, FacilityException;

public Collection<SbbLocalObject> getChildSbbs() throws TransactionRequiredLocalException, IllegalStateException, FacilityException;

public <T> Collection<T> getChildSbbs(Class<T> type) throws NullPointerException, TransactionRequiredLocalException, IllegalStateException, FacilityException;

public RhinoSbbLocalHome getChildSbbLocalHome(String name) throws NullPointerException, UnrecognizedChildRelationException, FacilityException;}

• All methods of the ChildRelationFacility interface, except for the getChildRelationNames method and the

getChildSbbLocalHome method, are required transactional methods. The getChildRelationNames method and

the getChildSbbLocalHome method are non-transactional.• The SLEE provides a concrete class implementing the ChildRelationFacility interface.• The methods of this interface throw the javax.slee.facilities.FacilityException if the requested operation

cannot be completed because of a system-level failure.

6.1.3 ChildRelationFacility interface getChildRelationNames method

The getChildRelationNames method returns the set of declarative child relation names declared by the SBB. Each name contained by this set

corresponds with a name contained by a <child-relation-name> element in the oc-sbb-jar.xml extension deployment descriptor.

92

Page 93: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.1.4 ChildRelationFacility interface getChildRelation method

The getChildRelation method returns a standard ChildRelation object for the named declarative child relation. The specified name

argument must be one of the names contained by the <child-relation-name> elements in the oc-sbb-jar.xml extension deployment

descriptor; that is, it must be one of the names contained in the set of names returned by the getChildRelationNames method.

This method performs the same function as the get child relation methods declared in the SBB abstract class for standard JAIN SLEE child

relation declarations. A ChildRelation object returned from this method can be used in exactly the same way as a ChildRelation object

returned by a get child relation method.

This method throws a NullPointerException if the name argument is null . If the name argument does not correspond with a declarative

child relation, then this method throws an UnrecognizedChildRelationException . If this method is invoked without a valid transaction

context, then the method throws a TransactionRequiredLocalException . If the method is invoked by an SBB object that is not assigned to

an SBB entity, then the method throws an IllegalStateException .

6.1.5 ChildRelationFacility interface getChildSbbs methods

The getChildSbbs methods each return a collection of child SBB local interface objects. The no-argument variant returns a collection of all child

SBBs. The one-argument variant returns a collection of all child SBBs where the child SBB’s local interface is assignable to the specified Class

argument. Both these methods will consider all SBB child relations; that is, child relations declared both in the standard JAIN SLEE manner and

declarative child relations.

If either of these methods are invoked without a valid transaction context then a TransactionRequiredLocalException is thrown. If invoked

by an SBB object that is not assigned to an SBB entity, then an IllegalStateException is thrown. If the one-argument method variant is

invoked with a null argument, then the method throws a NullPointerException .

6.1.6 ChildRelationFacility interface getChildSbbLocalHome method

The getChildSbbLocalHome method returns an object implementing the local home interface of the child SBB of the named declarative child

relation. For more information on SBB local home interfaces, please see Miscellaneous SLEE Application API Enhancements on page 55 .

This method throws a NullPointerException if the name argument is null . If the name argument does not correspond with a declarative

child relation, then this method throws an UnrecognizedChildRelationException .

93

Page 94: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.2 Usage extensions

The JAIN SLEE specification allows SLEE components such as SBBs and resource adaptors to define a single usage parameters interface for

the collection of runtime statistics. Statistics may be collected in different usage parameter sets — essentially named buckets each containing

the same set of usage parameters as defined by the usage parameters interface. Creation and removal of named usage parameter sets is only

supported through JMX management clients.

When building large SLEE applications or complex resource adaptors, the limitations of the SLEE-defined usage mechanism quickly becomes

apparent. A single usage parameters interface lacks flexibility, and means that statistics from all parts of the system need to be lumped into

a single view; and the inability of an application to be able to control its own named usage parameter sets can create a discord between any

dynamic application behaviour and usage parameter set management requirements.

To alleviate these problems, Rhino provides a usage extension mechanism that allows an SBB or resource adaptor to declare multiple usage

parameters interfaces, and defines a usage facility with which SBBs and resource adaptors can manage and access their own usage parameter

sets. This section describes that extension mechanism.

6.2.1 Usage parameter types

The JAIN SLEE specification defines two types of usage parameters: counter-type and sample-type. Rhino’s extension mechanism does not add

any new type of usage parameter, but does allow counter-type usage parameters to be set to a specific value rather than only incremented or

decremented.

6.2.2 Usage parameter sets

A usage parameter set is a set that contains a usage parameter for each usage parameter name declared in the usage parameters interface of the

corresponding SLEE component. Each method of the usage parameters interface declares the usage parameter name and type of a single usage

parameter in this set. A SLEE component that generates usage information may access multiple usage parameters with the same lowest-level

usage parameter name component, by using multiple usage parameter sets. The JAIN SLEE specification defines: a default usage parameter set,

automatically available to any SLEE component that defines a usage parameters interface; and named usage parameter sets — which can also

be used by the SLEE component, but can only be created and removed using the JMX management interface. Usage parameter sets in the JAIN

SLEE specification occupy a flat namespace, and there is no relationship between any two usage parameter sets.

94

Page 95: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Rhino’s extension mechanism introduces a hierarchical structure and namespace for usage parameter sets. The SLEE-defined default usage

parameter set is replaced with a root usage parameter set, and each usage parameter set can have zero or more child usage parameter sets. A

usage parameter set name must be unique amongst its sibling usage parameter sets, but in any other case usage parameter set names may be

reused.

A SLEE component creates, removes, or otherwise manages its own usage parameter sets itself using the Usage Facility and the methods

defined on the Usage Parameter Interfaces .

6.3 Usage parameter set types

Each usage parameter set may or may not have a type. Usage parameter set types are declared in the deployment descriptor, each with a

corresponding usage parameters interface. A usage parameter set with no type has no usage parameters, and can be used as a structural

placeholder in the usage parameter set hierarchy.

The type of the root usage parameter set is also declared in the deployment descriptor. This declaration is optional. If declared, the root usage

parameter set will be created with the specified type; otherwise the root usage parameter set will be created with no type.

The type of a child usage parameter set is specified at runtime when the usage parameter set is created by the SLEE component. A child usage

parameter set may be created with any recognised usage parameter set type, or may be created with no type.

A SLEE component must declare at least one usage parameter set type in order to use the usage facility and manage its usage parameter sets.

6.4 Aggregation and extension

Under certain conditions, a usage parameter update to a usage parameter set may aggregate to its parent usage parameter set. Aggregation

simply means that the update is also applied to the parent usage parameter set, and then its parent, and so on, so long as an aggregation

relationship holds between the parent and child usage parameter sets, or the root usage parameter set is reached. Aggregation is useful, for

example, to record total usage in a parent usage parameter set where individual child usage parameter sets record usage for different conditions,

such as the triggering protocol of the session.

Aggregation for a given usage parameter name can only occur from a child usage parameter set to a parent usage parameter set if:

• the parent usage parameter set and the child usage parameter set have the same usage parameter set type; or

95

Page 96: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• the child usage parameter set type extends, either directly or indirectly, the parent usage parameter set type; and both usage

parameter set types declare a usage parameter of the same type (counter-type or sample-type) with that usage parameter name.

Usage parameter set type extension is declarative rather than programmatic. A usage parameter set type declares in the deployment descriptor

if it extends another usage parameter set type. The usage parameters interface of a usage parameter set type that extends another usage

parameter set type is not required to extend or otherwise be related in any way to the usage parameters interface of the extended usage

parameter set type. As long as the two usage parameters interfaces declare a usage parameter with the same name and type (counter-type or

sample-type), then aggregation may occur between the two usage parameter set types for that usage parameter name.

Aggregation is enabled by default for all usage parameters. Aggregation can be disabled on a per usage parameter name basis using the relevant

annotation on page 100 on each usage parameters interface usage parameter method declaration.

6.5 Usage parameters interfaces

SLEE components declare their usage parameters using one or more usage parameters interfaces. Each usage parameters interface must be

defined according to the following rules:

• A usage parameters interface must be defined in a named package; in other words, the class must have a package declaration.

• A usage parameters interface must be declared as public .

• A usage parameters interface may optionally extend the

com.opencloud.rhino.facilities.usage.UsageParametersInterface interface.

• Each increment, set, or sample method within the usage parameters interface must declare a lowest-level usage parameter name

relevant to the SLEE component.

• The SLEE derives the usage parameter type associated with this usage parameter name from the method name of the

declared method.

• Each get accessor method within the usage parameters interface provides access to the current approximate value or sample

statistics for the lowest-level usage parameter name.

• A single usage parameter name can only be associated with a single usage parameter type. The SLEE will reject a usage parameters

interface that declares both a sample method and an increment or set method for the same usage parameter name.

96

Page 97: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• It is legal to declare both increment and set methods for the same usage parameter name. These two methods simply offer

alternative ways to update the same counter-type usage parameter.

• A usage parameter name must be a valid Java identifier and begin with a lowercase letter, as determined by

java.lang.Character.isLowerCase .

Counter-type usage parameter increment methods, sample-type usage parameter sample methods, and all usage parameter accessor methods,

are declared in the usage parameters interface as defined in the SLEE specification.

6.6 Counter-type usage parameter set method

A usage parameter set method must be defined in the usage parameters interface to declare the presence of and to permit updates to a counter-

type usage parameter. The method name of the set method is derived by adding a "set" prefix to the usage parameter name. The set method has

the following method signature:

public abstract void set<usage parameter name>(long value);

• The set method must be declared as public and abstract.• The first letter of the usage parameter name is uppercased in the definition of the set method.• The set method does not have a throws clause.• This method runs in an unspecified transaction context. Counter-type usage parameter updates do not require an active

transaction. Counter-type usage parameter updates occur regardless of the outcome of any transaction active at the time

of the update. If multiple threads update the same usage parameter at the same time, these updates are applied as if the

updates were serial.• The method throws a javax.slee.SLEEException if the requested operation cannot be performed due to a system-

level failure.

97

Page 98: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.7 UsageParametersInterface interface

A usage parameters interface may optionally extend the UsageParametersInterface . By extending this interface, a usage parameters

interface provides its corresponding usage parameter sets with easy access to methods reporting metadata about themselves and methods to

manage their child usage parameter sets. The UsageParametersInterface is shown below:

package com.opencloud.rhino.facilities.usage;

import java.util.Collection;import javax.slee.SLEEException;import javax.slee.usage.SampleStatistics;

public interface UsageParametersInterface { public String name(); public String type(); public String key(); public <T extends UsageParametersInterface> T getOrCreateChild(String name) throws NullPointerException, IllegalArgumentException, SLEEException; public <T extends UsageParametersInterface> T getOrCreateChild(String name, String type) throws NullPointerException, IllegalArgumentException, UnrecognizedUsageParameterSetTypeException, SLEEException; public boolean hasChild(String name) throws NullPointerException, SLEEException; public Collection<? extends UsageParametersInterface> children() throws SLEEException; public <T extends UsageParametersInterface> T parent() throws SLEEException; public void remove() throws SLEEException;}

All methods in the UsageParametersInterface are non-transactional methods; that is, they do not require an active transaction to return a

successful result, and their effects persist regardless of the outcome of any transaction active at the time of the method call.

The methods throw a SLEEException if the requested operation cannot be performed due to a system-level failure.

98

Page 99: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.7.1 UsageParametersInterface interface name method

The name method returns the name of the usage parameter set that the UsageParametersInterface object is providing usage access to. This

name is the name that the usage parameter set was created with. The root usage parameter set has no name; therefore this method will return

null if invoked on the root usage parameter set.

6.7.2 UsageParametersInterface interface type method

The type method returns the type name of the usage parameter set that the UsageParametersInterface object is providing usage access to.

If the usage parameter set was created with no type, this method returns null .

6.7.3 UsageParametersInterface interface key method

The key method returns a unique identifier that identifies the usage parameter set that the UsageParametersInterface object is providing

usage access to. The key differs from the parameter set name in that the key is an absolute identifier that takes into account the usage parameter

set’s place in the usage parameter set hierarchy, and is able to identify the usage parameter set without any other context; whereas the usage

parameter set name is relative to the usage parameter set’s parent usage parameter set only.

6.7.4 UsageParametersInterface interface getOrCreateChild methods

The getOrCreateChild methods return the child usage parameter set with the name specified by the name argument. If the usage parameter

set already exists, then the existing usage parameter set is returned; otherwise a new usage parameter set is created. If a new usage parameter

set is created, and the type argument is specified, then the child usage parameter set is created with the specified type; otherwise it is created

with the same type as the usage parameter set the method is invoked on.

These methods throw a NullPointerException if the name argument is null . The methods throw an IllegalArgumentException if the

name argument is zero-length. If the type argument is specified and not null , but is not recognised as a defined usage parameters interface

type, the method throws an UnrecognizedUsageParameterSetTypeException .

6.7.5 UsageParametersInterface interface hasChild method

The hasChild method returns a Boolean value indicating if a child usage parameter set with a name equal to the name argument currently exists.

This method throws a NullPointerException if the name argument is null .

99

Page 100: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.7.6 UsageParametersInterface interface children method

The children method returns a collection containing all the child usage parameter sets of the usage parameter set that the

UsageParametersInterface object is providing usage access to.

6.7.7 UsageParametersInterface interface parent method

The parent method returns the usage parameter set that is the parent of the usage parameter set that the UsageParametersInterface

object is providing usage access to. If the UsageParametersInterface object represents the root usage parameter set, then this method

returns null .

6.7.8 UsageParametersInterface interface remove method

The remove method removes the usage parameter set that the UsageParametersInterface object is providing usage access to. All child

usage parameter sets are also removed, recursively.

The root usage parameter set cannot be removed; however, this method may be invoked on a root usage parameter set, in which case the

following behaviour is observed:

• All child usage parameter sets are removed as usual.

• All usage parameters in the root usage parameter set are reset to their initial value, as if the root usage parameter set had been

removed and recreated in a single atomic action.

6.8 Annotations

A usage parameters interface and its usage parameter methods may all be annotated to provide additional information to Rhino’s statistics and

SNMP subsystems. This is supported in both the SLEE-defined usage mechanism and Rhino’s extension mechanism. Information provided to the

statistics subsystem helps clients display statistics appropriately, whereas information provided to the SNMP subsystem is used to configure the

OIDs included in SNMP notifications for usage parameter set updates.

6.8.1 @UsageParameters annotation

A usage parameters interface may be annotated with the @UsageParameters annotation. The @UsageParameters annotation is shown below:

100

Page 101: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

package com.opencloud.rhino.facilities.usage;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface UsageParameters { String description() default ""; String oid() default "";}

• The description parameter provides a general description for the usage parameters interface.• The oid parameter defines the base SNMP Object Identifier (OID) to use for all the usage parameter sets created from

the usage parameters interface. The base OID must be specified using dotted string notation, such as 1.3.6.1.4.

1.19808.2.1.1001 . If a base OID is not specified, or is specified as a zero-length string, then a base OID is

dynamically generated for the usage parameters interface. See SNMP statistics for OID detailed explanation.

When installing a SLEE component that has default oid parameter specified, please make sure the base oid mapping is not in-use.Otherwise a duplicate oid mapping alarm will be raised. If the mapping is in-use, rhino console commands setsnmpoidmapping orremovesnmpmappingconfig can be used to clear/remove it.

6.8.2 @UsageCounter annotation

A counter-type usage parameter increment or set method may be annotated with the @UsageCounter annotation. The @UsageCounter

annotation is shown below:

package com.opencloud.rhino.facilities.usage;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface UsageCounter { String description() default ""; CounterType counterType();

101

Page 102: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

boolean aggregate() default true; String shortName() default ""; String unitLabel() default ""; int mapping() default -1;}

• The description parameter provides a general description for the usage parameter.• The counterType parameter identifies the specific type of counter that the usage parameter represents. A counter-type

usage parameter may be one of the following subtypes:

• counter — an unbounded counter that typically only either increments or decrements.• gauge — a counter that typically has a lower and/or upper bound with a value that may oscillate within the

bounds.• The aggregate parameter indicates whether or not updates to the usage parameter may aggregate on page 95 to

the parent usage parameter set.• The shortName parameter defines a short, possibly abbreviated version of the usage parameter name.• The unitLabel parameter specifies a label for the counter’s unit type.• The mapping parameter specifies a numeric SNMP ID for the usage parameter. This ID is appended to the usage

parameter interface’s base SNMP OID to form the OID of the usage parameter. Defining a static ID for each usage

parameter can eliminate renumbering issues if the usage parameters interface is later expanded with new usage

parameters.

If both an increment method and a set method are defined for a single counter-type usage parameter, and both methods are annotated with

@UsageCounter , then Rhino will arbitrarily choose one of the annotations to use for the usage parameter, and ignore the other annotation. In

this case it is recommended only one of the methods be annotated.

6.8.3 @UsageSample annotation

A sample-type usage parameter sample method may be annotated with the @UsageSample annotation. The @UsageSample annotation is shown

below:

package com.opencloud.rhino.facilities.usage;

102

Page 103: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface UsageSample { String description() default ""; SampleUnits sourceUnits(); SampleUnits displayUnits(); boolean aggregate() default true; String shortName() default ""; String unitLabel() default "";}

• The description parameter provides a general description for the usage parameter.• The sourceUnits parameter identifies the units that the sample values are recorded with. Units must be one of: time in

seconds, time in milliseconds, time in nanoseconds, or a dimensionless count.• The displayUnits parameter identifies the units with which the sample statistics should be displayed.

• This parameter has no effect on how sample values are reported when using a JMX Usage MBean interface

to inspect usage parameters. The parameter is only meaningful to statistics clients using Rhino’s proprietary

statistics API.• The aggregate parameter indicates whether or not updates to the usage parameter may aggregate on page 95 to

the parent usage parameter set.• The shortName parameter defines a short, possibly abbreviated, version of the usage parameter name.• The unitLabel parameter specifies a label for the sample’s unit type.

6.9 SBB usage parameters interface deployment descriptor

If an SBB declares one or more usage parameters interfaces using the Rhino usage extension mechanism, the oc-sbb-jar.xml Rhino

extension deployment descriptor of the SBB must identify the usage parameters interfaces. The sbb-usage-parameters-interfaces

element of the SBB extension deployment descriptor identifies these interfaces. It contains the following sub-elements:

103

Page 104: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

Sub-element What it does

description This is an optional informational element.

sbb-usage-parameters-interface Each usage parameters interface type defined by the SBB must be identified by a

sbb-usage-parameters-interface element.

Each sbb-usage-parameters-interface element has the following attributes and sub-elements:

Sub-element or attribute What it does

root This attribute indicates if this usage parameters interface should be used as the root

usage parameter set type on page 94 . At most one usage parameters interface

may be declared as the root usage parameter set type.

description This is an optional informational element.

sbb-usage-parameters-interface-type This element specifies the usage parameters interface type name. This type name

identifies the usage parameters interface when creating new child usage parameter

sets. Each usage parameters interface declared in the deployment descriptor must

have a unique type name.

sbb-usage-parameters-interface-name This element identifies the interface name of the usage parameters interface.

The sbb-usage-parameters-interface-type element has the following attribute:

Attribute What it does

extends This attribute indicates if the usage parameters interface type extends on page 95

another usage parameters interface type. The extends attribute contains the type

104

Page 105: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

name of the usage parameters interface that this usage parameters interface type

extends.

6.10 Resource adaptor usage parameters interface deployment descriptor

If a resource adaptor declares one or more usage parameters interfaces using the Rhino usage extension mechanism, the oc-resource-

adaptor-jar.xml Rhino extension deployment descriptor of the resource adaptor must identify the usage parameters interfaces. The

resource-adaptor-usage-parameters-interfaces element of the resource adaptor extension deployment descriptor identifies these

interfaces. It contains the following sub-elements:

Sub-element What it does

description This is an optional informational element.

resource-adaptor-usage-parameters-interface Each usage parameters interface type defined by the resource adaptor

must be identified by a resource-adaptor-usage-parameters-

interface element.

Each resource-adaptor-usage-parameters-interface element has the following attributes and sub-elements:

Sub-element or attribute What it does

root This attribute indicates if this usage parameters interface should be used as the root

usage parameter set type on page 95 . At most one usage parameters interface

may be declared as the root usage parameter set type.

description This is an optional informational element.

resource-adaptor-usage-parameters-interface-type

This element specifies the usage parameters interface type name. This type name

identifies the usage parameters interface when creating new child usage parameter

105

Page 106: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

sets. Each usage parameters interface declared in the deployment descriptor must

have a unique type name.

resource-adaptor-usage-parameters-interface-name

This element identifies the interface name of the usage parameters interface.

The resource-adaptor-usage-parameters-interface-type element has the following attribute:

Attribute What it does

extends This attribute indicates if the usage parameters interface type extends on page 95

another usage parameters interface type. The extends attribute contains the type

name of the usage parameters interface that this usage parameters interface type

extends.

6.11 Usage facility

The usage facility is used by SBBs and resource adaptors to obtain access to their root usage parameter set and to create and manage child

usage parameter sets. The usage facility is defined by the com.opencloud.rhino.facilities.usage.UsageFacility interface. An SBB

obtains access to a UsageFacility object using a JNDI name lookup. A resource adaptor obtains access to a UsageFacility object from the

ConfigProperties object passed to it by the SLEE.

A UsageFacility object is only made available to SLEE components that declare usage parameter interfaces using the Rhino usage extension

mechanism. A SLEE component that does not declare any usage parameters interface, or declares a usage parameters interface using the SLEE-

defined mechanism, will not be able to access the usage facility.

6.11.1 UsageFacility interface

The com.opencloud.rhino.facilities.usage.UsageFacility interface is shown below:

package com.opencloud.rhino.facilities.usage;

import java.util.Collection;

106

Page 107: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import javax.slee.facilities.FacilityException;

public interface UsageFacility { public static final String JNDI_NAME = "java:comp/env/slee/facilities/usage"; public static final String CONFIG_PROPERTY_NAME = "slee-vendor:com.opencloud.rhino.facilities.usage";

public <T extends UsageParametersInterface> T getRootUsageParameterSet();

public <T extends UsageParametersInterface> T getUsageParameterSet(String key) throws NullPointerException, UnrecognizedUsageParameterSetException, FacilityException;

public <T extends UsageParametersInterface> T getOrCreateChild(UsageParametersInterface parent, String name) throws NullPointerException, IllegalArgumentException, UnrecognizedUsageParameterSetException, FacilityException;

public <T extends UsageParametersInterface> T getOrCreateChild(UsageParametersInterface parent, String name, String type) throws NullPointerException, IllegalArgumentException, UnrecognizedUsageParameterSetException, UnrecognizedUsageParameterSetTypeException, FacilityException;

public boolean hasChild(UsageParametersInterface parent, String name) throws NullPointerException, UnrecognizedUsageParameterSetException, FacilityException;

public Collection<? extends UsageParametersInterface> getChildren(UsageParametersInterface parent) throws NullPointerException, FacilityException;

public void removeUsageParameterSet(UsageParametersInterface paramSet) throws NullPointerException, UnrecognizedUsageParameterSetException, FacilityException;}

• The JNDI_NAME constant specifies the JNDI location where a UsageFacility object may be located by an SBB

component in its component environment.• The CONFIG_PROPERTY_NAME constant specifies the configuration property name where a UsageFacility object

may be located by a resource adaptor component in the ConfigProperties object passed to it in the raVerifyCo

nfiguration , raConfigure , and raConfigurationUpdate methods.

107

Page 108: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

• All methods of the UsageFacility interface are non-transactional methods.• The SLEE provides a concrete class implementing the UsageFacility interface.• The methods of this interface throw the javax.slee.facilities.FacilityException if the requested operation

cannot be completed because of a system-level failure.

6.11.2 UsageFacility interface getRootUsageParameterSet method

The getRootUsageParameterSet method returns the root usage parameter set for the SLEE component. If the SLEE component declares a

root usage parameter set type, then the object returned from this method will be castable to the corresponding usage parameters interface for that

type.

6.11.3 UsageFacility interface getUsageParameterSet method

The getUsageParameterSet method returns the usage parameter set with the key specified by the key argument. A usage parameter set’s

identifying key can be obtained using the key on page 99 method of the UsageParametersInterface interface.

The usage parameter set object returned from this method will be castable to the usage parameters interface corresponding with its type, as

returned by the type on page 99 method of the UsageParametersInterface interface.

This method throws a NullPointerException if the key argument is null . The method throws an

UnrecognizedUsageParameterSetException if no usage parameter set currently exists with the specified key.

6.11.4 UsageFacility interface getOrCreateChild methods

The getOrCreateChild methods return the child usage parameter set of the usage parameter set specified by the parent argument with the

name specified by the name argument. If the usage parameter set already exists, then the existing usage parameter set is returned; otherwise a

new usage parameter set is created. If a new usage parameter set is created, and the type argument is specified, then the child usage parameter

set is created with the specified type; otherwise it is created with the same type as the usage parameter set the method is invoked on.

These methods throw a NullPointerException if the name argument is null . The methods throw an

UnrecognizedUsageParameterSetException if the parent argument is not recognised by this usage facility object, for example if the

usage parameter set was created by some other usage facility object. The methods throw an IllegalArgumentException if the name

108

Page 109: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

argument is zero-length. If the type argument is specified and not null , but is not recognised as a defined usage parameters interface type, the

method throws an UnrecognizedUsageParameterSetTypeException .

6.11.5 UsageFacility interface hasChild method

The hasChild method returns a boolean value indicating if the usage parameter set identified by the parent argument contains a child usage

parameter set with a name equal to the name argument.

This method throws a NullPointerException if the name argument is null . This method throws an

UnrecognizedUsageParameterSetException if the parent argument is not recognised by this usage facility object, for example if the

usage parameter set was created by some other usage facility object.

6.11.6 UsageFacility interface getChildren method

The getChildren method returns a collection containing all the child usage parameter sets of the usage parameter set identified by the parent

argument.

This method throws a NullPointerException if the parent argument is null .

6.11.7 UsageFacility interface removeUsageParameterSet method

The getRootUsageParameterSet method removes the usage parameter set identified by the paramSet argument. All child usage parameter

sets are also removed, recursively.

This method throws a NullPointerException if the paramSet argument is null . This method throws an

UnrecognizedUsageParameterSetException if the paramSet argument is not recognised by this usage facility object, for example if the

usage parameter set was created by some other usage facility object.

6.12 Profile facility extensions

Rhino extends the standard javax.slee.facilities.ProfileFacility interface with the

com.opencloud.rhino.facilities.profile.ProfileFacility interface, which adds additional functionality over what the JAIN SLEE

specification provides.

109

Page 110: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.12.1 ProfileFacility interface

The com.opencloud.rhino.facilities.profile.ProfileFacility interface is shown below:

package com.opencloud.rhino.facilities.profile;

import javax.slee.facilities.FacilityException;import javax.slee.profile.UnrecognizedProfileTableNameException;

public interface ProfileFacility extends javax.slee.profile.ProfileFacility { public boolean profileTableExists(String profileTableName) throws NullPointerException, FacilityException;

public ProfileTableDescriptor getProfileTableDescriptor(String profileTableName) throws NullPointerException, UnrecognizedProfileTableNameException, FacilityException;

public Class<?> getProfileLocalInterface(String profileTableName) throws NullPointerException, UnrecognizedProfileTableNameException, FacilityException;}

The extended interface is implemented by all ProfileFacility objects provided by Rhino to SBBs and resource adaptors.

The extended interface adds two new methods to the profile facility. Both methods are non-transactional; that is, they do not require an active

transaction to return a successful result. The methods throw the javax.slee.facilities.FacilityException if the requested operation

cannot be completed because of a system-level failure.

6.12.2 ProfileFacility interface profileTableExists method

The profileTableExists method returns a boolean value that reports whether or not a profile table with the name specified by the

profileTableName argument currently exists in the SLEE.

This method throws a NullPointerException if the profileTableName argument is null .

6.12.3 ProfileFacility interface getProfileTableDescriptor method

The getProfileTableDescriptor method returns a metadata object that provides information about the profile table with the name specified

by the profileTableName argument. The ProfileTableDescriptor interface is described below.

110

Page 111: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

This method throws a NullPointerException if the profileTableName argument is null . The method throws an

UnrecognizedProfileTableNameException if no profile table exists with the name specified by the profileTableName argument.

6.12.4 ProfileFacility interface ProfileTableDescriptor interface

The ProfileTableDescriptor interface provides metadata information about a profile table. This information might be useful, for example, to

determine if a profile table contains profiles of an expected type before querying the profile table or retrieving profiles from it.

The ProfileTableDescriptor interface is shown below:

package com.opencloud.rhino.facilities.profile;

import javax.slee.profile.ProfileSpecificationID;import javax.slee.profile.ProfileTable;

public interface ProfileTableDescriptor { public ProfileSpecificationID getProfileSpecification();

public Class<? extends ProfileTable> getProfileTableInterface();

public Class<?> getProfileLocalInterface();}

All methods in the ProfileTableDescriptor interface are non-transactional methods.

6.12.5 ProfileFacility interface getProfileSpecification method

The getProfileSpecification method returns the component identifier of the profile specification of the profile table the metadata object

describes.

6.12.6 ProfileFacility interface getProfileTableInterface method

The getProfileTableInterface method returns the Class object of the profile table interface declared by the profile specification of the

profile table the metadata object describes. If the profile specification does not declare a profile table interface, then this method returns the Class

object for the default SLEE-defined javax.slee.profile.ProfileTable interface instead.

111

Page 112: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.12.7 ProfileFacility interface getProfileLocalInterface method

The getProfileLocalInterface method returns the Class object of the profile local interface declared by the profile specification of the

profile table the metadata object describes. If the profile specification does not declare a profile local interface, then this method returns the Class

object of the profile CMP interface instead.

6.13 Tracer extensions

Rhino extends the standard javax.slee.Tracer interface with the com.opencloud.rhino.facilities.Tracer interface, which adds

additional functionality over what the JAIN SLEE specification provides.

6.13.1 Tracer interface

The com.opencloud.rhino.facilities.Tracer interface is shown below:

package com.opencloud.rhino.facilities;

import javax.slee.facilities.FacilityException;

public interface Tracer extends javax.slee.facilities.Tracer { public Tracer getParentTracer();

public Tracer getChildTracer(String name) throws NullPointerException, IllegalArgumentException, FacilityException;}

The extended interface is implemented by all Tracer objects provided by Rhino to SBBs, profiles, and resource adaptors.

The extended interface adds two new methods to the standard tracer. Like all methods defined by the standard interface, both new methods are

non-transactional; that is, they do not require an active transaction to return a successful result.

6.13.2 Tracer interface getParentTracer method

The getParentTracer method returns a Tracer object for the tracer’s parent tracer. The parent tracer is the tracer with the name returned by

the getParentTracerName method defined in the standard Tracer interface.

112

Page 113: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

If this method is invoked on a Tracer object for a root tracer, then null is returned.

6.13.3 Tracer interface getChildTracer method

The getChildTracer method returns a Tracer object for a tracer that is a descendant (in terms of a parent-child relationship) of the invoked

tracer. The name argument specifies the name of the child tracer.

Formally:

• if the invoked tracer is a root tracer, then this method returns a tracer with the name specified by the name argument

• otherwise, this method returns a tracer with the name: invokedTracer.getName() + . + name .

The name argument must be a valid tracer name. Since any valid name can be specified, this method can be used to create any descendant

tracer — child, grandchild, and so on.

This method throws a NullPointerException if the name argument is null . It throws an IllegalArgumentException if the name

argument would result in an invalid tracer name. It throws a javax.slee.facilities.FacilityException if the child tracer cannot be

returned because of a system-level failure.

6.14 Lock Facility

The lock facility allows resource adaptors to obtain transaction-based distributed locks.

In order to use the lock facility, one must obtain:

• a reference to the LockFacility itself; and

• a reference to the SLEE Transaction Manager, as all locks must be obtained from within a transaction.

The following code fragment illustrates how you can obtain these references in a resource adaptor:

package ...

import javax.slee.resource.ConfigProperties;import javax.slee.resource.ResourceAdaptor;import javax.slee.resource.ResourceAdaptorContext;

113

Page 114: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

import javax.slee.transaction.SleeTransactionManager;import com.opencloud.rhino.facilities.lock.LockFacility;

public class FooResourceAdaptor implements ResourceAdaptor { @Override public void setResourceAdaptorContext(ResourceAdaptorContext context) { // save context ref this.context = context;

// ... }

@Override public void raConfigure(ConfigProperties configProps) { // get refs to transaction manager and lock facility txManager = context.getSleeTransactionManager(); lockFacility = (LockFacility)configProps.getProperty(LockFacility.CONFIG_PROPERTY_NAME).getValue();

// ... }

// ...

private ResourceAdaptorContext context; private SleeTransactionManager txManager; private LockFacility lockFacility;}

With these references, one can then proceed to acquire locks as necessary. For example:

private void doSomeWorkThatRequiresALock() { // start a transaction SleeTransaction tx = txManager.beginSleeTransaction(); try { // acquire exclusive lock lockFacility.acquireExclusive("SomeLock");

// do the work

114

Page 115: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

// ...

// successfully completed work - commit transaction // automatically causes the lock to be released tx = null; txManager.commit(); } catch (Exception e) { if (tx != null) { // failed to complete work - rollback transaction // automatically causes the lock to be released tx.rollback(); } }}

6.15 JNDI environment metadata

The JAIN SLEE specification defines that an SBB component has access to a JNDI API namespace where it may obtain access to various SLEE

facilities and factories. Using the JNDI API for name lookups in SBB code generally works when you know exactly what you’re looking for, but

an SBB that uses SBB parts on page 68 may have entries in its JNDI namespace introduced by those SBB parts that may not be known at SBB

compile time but are still of interest to the SBB. The JNDI API does not differentiate one binding from another; so it’s not easy for an SBB, for

example, to find all resource adaptor entity bindings.

As an extension, Rhino provides all JNDI environment bindings to an SBB or SBB part in a separate map structure. The map is keyed on the fully

qualified binding name, with map values containing metadata about the type of binding as well as the bound object itself.

An SBB obtains access to the JNDI bindings map from its RhinoSbbContext object (a Rhino extension of SbbContext ):

package com.opencloud.rhino.slee;

import java.util.Map;import javax.slee.SLEEException;import javax.slee.SbbContext;import com.opencloud.rhino.slee.environment.JndiBinding;

115

Page 116: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public interface RhinoSbbContext extends SbbContext { public Map<String,JndiBinding> getJndiBindings() throws SLEEException;

...}

An SBB part obtains access to the JNDI bindings map from its SbbPartContext object:

package com.opencloud.rhino.slee.sbbpart;

import java.util.Map;import javax.slee.SLEEException;import javax.slee.SbbContext;import com.opencloud.rhino.slee.environment.JndiBinding;

public interface SbbPartContext extends SbbContext { public Map<String,JndiBinding> getJndiBindings() throws SLEEException;

...}

6.15.1 JndiBinding class

The com.opencloud.rhino.slee.environment.JndiBinding class is shown below:

package com.opencloud.rhino.slee.environment;

public abstract class JndiBinding { public abstract BindingType getType(); public String getJndiName() { ... } public Object getValue() { ... }

public boolean equals(Object o) { ... } public int hashCode() { ... }}

116

Page 117: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.15.2 JndiBinding class getType method

The getType method returns the type of the JNDI binding. The BindingType enumeration is shown below:

package com.opencloud.rhino.slee.environment;

public enum BindingType { ENV_ENTRY, ACTIVITY_CONTEXT_INTERFACE_FACTORY, RESOURCE_ADAPTOR_ENTITY, FACILITY, LIMITER_ENDPOINT}

A JNDI binding may be one of:

• an environment entry

• an activity context interface factory, such as the null activity context interface factory

• a resource adaptor entity link binding

• a SLEE facility, such as the timer facility and alarm facility

Activity factories, such as the null activity factory and service activity factory are considered to be SLEEfacilities for this purpose.

• a configured Rhino limiter endpoint.

6.15.3 JndiBindingclass getJndiName method

The getJndiName method returns the fully qualified name of the JNDI binding. This value is equal to the key that the JndiBinding object is

stored with in the map of bindings.

6.15.4 JndiBindingclass getValue method

The getValue method returns the object bound to the JNDI name. For example, this could be an environment entry value, a SLEE facility, and so

on.

117

Page 118: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.15.5 Subclasses of JndiBinding

The JndiBinding class is an abstract class. A subclass of JndiBinding exists for each different type of binding. Each of these is described

below.

6.15.6 EnvEntry class

The EnvEntry class is used to describe a JNDI binding for an environment entry. The EnvEntry class is shown below:

package com.opencloud.rhino.slee.environment;

public final class EnvEntry extends JndiBinding { public EnvEntry(String jndiName, Object value) { ... } public BindingType getType() { return BindingType.ENV_ENTRY; } public String toString() { ... }}

6.15.7 Facility class

The Facility class is used to describe a JNDI binding for a SLEE facility such as the timer facility as well as activity factories such as the null

activity factory. The Facility class is shown below:

package com.opencloud.rhino.slee.environment;

public final class Facility extends JndiBinding { public Facility(String jndiName, Object value) { ... } public BindingType getType() { return BindingType.FACILITY; } public String toString() { ... }}

6.15.8 LimiterEndpoint class

The LimiterEndpoint class is used to describe a JNDI binding for a configured limiter endpoint . The LimiterEndpoint class is shown

below:

package com.opencloud.rhino.slee.environment;

118

Page 119: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

public final class LimiterEndpoint extends JndiBinding { public LimiterEndpoint(String jndiName, Object value) { ... } public BindingType getType() { return BindingType.LIMITER_ENDPOINT; } public String toString() { ... }}

6.15.9 ResourceAdaptorTypeBinding class

The ResourceAdaptorTypeBinding class is the superclass for JNDI binding metadata classes related to resource adaptor types. The

ResourceAdaptorTypeBinding class is shown below:

package com.opencloud.rhino.slee.environment;

import javax.slee.resource.ResourceAdaptorTypeID;

public abstract class ResourceAdaptorTypeBinding extends JndiBinding { public ResourceAdaptorTypeID getResourceAdaptorType() { ... } public int hashCode() { ... }}

The getResourceAdaptorType method returns the component identifier of the resource adaptor type that the binding is associated with.

6.15.10 ActivityContextInterfaceFactoryBinding class

The ActivityContextInterfaceFactoryBinding class is used to describe a JNDI binding for an activity context interface factory. The

ActivityContextInterfaceFactoryBinding class is shown below:

package com.opencloud.rhino.slee.environment;

import javax.slee.resource.ResourceAdaptorTypeID;

public final class ActivityContextInterfaceFactoryBinding extends ResourceAdaptorTypeBinding { public ActivityContextInterfaceFactoryBinding(String jndiName, ResourceAdaptorTypeID raType, Object value) { ... } public BindingType getType() { return BindingType.ACTIVITY_CONTEXT_INTERFACE_FACTORY; } public String toString() { ... }}

119

Page 120: Rhino Extended APIs...Rhino Extended APIs (V2.5.0) 3.2.3 Datatype codecs.....31

Rhino Extended APIs (V2.5.0)

6.15.11 ResourceAdaptorEntityBinding class

The ResourceAdaptorEntityBinding class is used to describe a JNDI binding for a resource adaptor entity. The

ResourceAdaptorEntityBinding class is shown below:

package com.opencloud.rhino.slee.environment;

import javax.slee.resource.ResourceAdaptorTypeID;

public final class ResourceAdaptorEntityBinding extends ResourceAdaptorTypeBinding { public ResourceAdaptorEntityBinding(String jndiName, ResourceAdaptorTypeID raType, Object value) { ... } public BindingType getType() { return BindingType.RESOURCE_ADAPTOR_ENTITY; } public String toString() { ... }}

120