| Solstice Enterprise Manager 4.1 Developing C++ Applications |
Developing Object Behaviors
The Object Development Tools (ODT) of Solstice EM provide a simple and automated framework for adding and writing behaviors for managed objects residing in the Solstice EM MIS. You can define objects and their behaviors by using GDMO and ASN.1.
The GDMO definitions formally specify the syntaxes of attributes, actions and notifications. This defines the interface to the object, which is formally specified using ASN.1. The state changes that the object undergoes as a result of the action or operation on the object or as a result of internal changes (perhaps resulting in the creation of notifications) are specified in an informal way in GDMO english text as object behavior. When implementing an object, the developers need to translate this text into a formal state machine in a programming language such as C++.
This chapter explains how to use the Solstice EM object development tools (ODT) to develop object behaviors.
- Section 10.1 ODT Overview
- Section 10.2 Object Interfaces
- Section 10.3 Object Development Overview
- Section 10.4 Object Code Generator Utility
- Section 10.5 Implementing GDMO Specified Object Behavior
- Section 10.6 Debugging Objects
- Section 10.7 Generated Files
- Section 10.8 TRY Exception Macros
- Section 10.9 Object Development Examples
- Section 10.10 Object Development Scenario Using Chai Object
10.1 ODT Overview
The ODT allows you to perform the following operations:
- Generate code and interfaces required to support object behavior for a GDMO/ASN.1-defined object.
- Add or remove attributes from the GDMO definition and re-generate the code and interfaces.
- Add or remove actions from the GDMO definition and re-generate the code and interfaces.
- Add or remove notifications from the GDMO definition and re-generate the code and interfaces.
- Switch from using default behaviors to API-user-extended behaviors without re-generating the code and interfaces.
- Add or remove discriminators from the GDMO definition and re-generate the code and interfaces.
- Specify persistence or volatility for the attributes of an object class.
- Create and initialize an instance of a new object after the GDMO for it has been loaded.
The ODT lets you define behavior for actions or define behavior for generating any event, not just the standard ones. ODT also lets you define behavior when attributes are accessed or when object instances are created and deleted.
10.1.1 Supporting Functions
To provide a useful object implementation, Solstice EM provides the following supporting functions:
- Ability to invoke operations on an object
- Response/error generation
- Standard event generation
- Transaction management
- Lock management
- Persistence
- Concurrent access to objects
- MIT management
- Scoping and filtering support
- Validation of user requests (For example, DELETE, GET, SET, and CREATE operations for an object follow rules defined in the GDMO.)
- Automatic instance naming
These supporting functions are hidden within the Solstice EM platform and are used transparently by the user-defined implementation code generated by ODT.
10.1.2 Object Development Components
FIGURE 10-1 shows the major components and interfaces the ODT provides or uses:
![]()
FIGURE 10-1 ODT components10.2 Object Interfaces
The ODT provides object interfaces for object developers to use when implementing agent or manager-role behaviors using the ODT. The object interfaces are:
- Object Behavior Interface (OBI)
- Object Services Application Programming Interface (OSAPI)
10.2.1 Object Behavior Interface
The Object Behavior Interface (OBI) provides functions that allow the MIS to invoke (or request) object behavior functions developed by an API user and receive responses from the user developed functions.
It provides the following functions:
- Attribute access implementing behavior for GET and SET CMIP operations
- Action access implementing CMIP ACTION operation
- Instantiation access implementing behavior for CREATE, DELETE CMIP operation
- Notification behavior implementing event generation and behavior to be executed on receipt of events
A large part of the software in this interface is generated code. This interface also contains generated stub function interfaces (also referred to as stubs) where you can add your own object behavior code. To write unique object behavior code, you may use the Object Services API or write your own C++ code.
Generated stub function interfaces are provided for the following:
- Each attribute defined for a GDMO object class
- Each action defined for a GDMO object class
- Handling the receipt of notifications by an object
- Handling special instantiation and deletion behavior defined for a GDMO object class
You are required to provide functionality for only the action stub function interface and not for the other stubs functions interfaced. If you do not provide functionality, default behavior functionality is used.
10.2.2 Object Services API
The Object Services API (OSAPI) lets you access services provided by the MIS to implement inter-object behaviors or specialized behaviors. Framework utilities provide capabilities for building, loading, unloading, and instantiating objects.
The decision to use these services depends on the behavior defined for an object. For example, if an action defined for a GDMO object requires the object to check the administrativeState of the log object as part of the action, the user-developed behavior code needs to use the object services interface to issue a get request to obtain the value of the administrativeState attribute of the log object.
The OSAPI provides the following set of services that can be used within an object implementation:
- Issue a get request and (asynchronously) receive any responses
- Issue a set request and (asynchronously) receive any responses
- Issue a create request and (asynchronously) receive any responses
- Issue a delete request and (asynchronously) receive any responses
- Issue an action request and (asynchronously) receive any responses
- Issue an unconfirmed event report request
10.3 Object Development Overview
The process for defining and implementing object behavior is as follows:
1. Define object classes.
- Define and develop Managed Object Class (MOC) using GDMO and ASN.1 definitions to include the behaviors for the MOC. If you have existing GDMO and ASN.1 documents that define the appropriate behaviors, you can use those existing files.
2. Compile and load MOC into MDR.
- Use the GDMO/ASN.1 compiler to compile and load the GDMO and ASN.1 files into the Meta-Data Repository (MDR).
3. Generate object code and develop behavior.
- Use the Object Code Generator (OCG) utility to generate the default object implementation for the MOC. The OCG generates function stub interfaces, a Makefile, object loading and unloading utilities, an object instantiation program, and a README file that contains instructions about the generated files and how to extend the default implementation.
- To develop additional behavior, add C++ code at insert areas clearly identified in the generated code. The code you add implements behaviors that are defined in GDMO for the MOC.
- Refer to section__________
4. Compile and build object implementation source.
- Use the OCG-generated Makefile.className to build default or user-extended object implementation. The Makefile builds the object implementation as a dynamic library and a PMI client program for instantiating the object.
5. Load object implementation and restart MIS.
- Use the object loading utility, className.load, to load the new object implementation into the platform. Then, restart the MIS (using em_services -start) to read the new object implementation. When the MIS restarts, the new object implementation is loaded dynamically into the em_mis process. Subsequent CMIP operation on an object instance for this object class results in executing the behavior implemented by the user.
6. Debug object implementation [optional]
- User-implemented behaviors might contain errors which result in operation failures and, in some instances, MIS crashes. You can use a debugger to attach to the running MIS or directly debug em_mis to debug new object implementations. Using em_debug, you can enable or disable developer-provided object-operation traces at runtime.
For a complete scenario that illustrates this process, see Section10.10 Object Development Scenario Using Chai Object."
10.3.1 Possible Errors
Errors can occur in the following phases of object behavior definition:
- GDMO object class definition
The GDMO and ASN.1 compiler identify syntax errors in your GDMO and ASN.1 documents. For the Object Code Generator to generate appropriate code, you must provide complete and syntactically correct GDMO and ASN.1 object definition.
- GDMO object class composition
When the MIS restarts, the object class definition and behavior definition are composed and registered. Any errors in this phase display on your screen.
- Object class instantiation
When an instance of a class is created, any problems in creating an instance arising out of an improper object definition are returned as an error for the create request.
- User-developed code
If you add any user-defined code to the generated code, you might introduce errors.
10.3.2 Sanity Check Procedure
It might not be possible to detect all GDMO or ASN.1 errors using the GDMO/ASN.1 compiler or the object implementation process, for example, OID registration clashes, name binding and attribute mismatches for initial values, default values, and so on. Sometimes, late in your object development process, you may find errors or failures that result from errors in the GDMO or ASN.1 definition for the MOC. Use the following sanity-check procedure to minimize potential problems:
1. Comment out ACTION definitions in GDMO.
- Comment out the ACTION definitions in the GDMO definition for the object class. You must do this because you cannot compose an object class that contains actions without loading the appropriate action implementation in a dynamic library.
2. Compile and load object class in MDR.
3. Compose object class.
- Use the compose program to compose the new object class. This verifies the OIDs, attributes, and syntax and catches such errors as clashes with existing classes, attribute mismatches, and invalid syntax (referring to a different document/syntax label that is valid but not actually desired by the object implementor). Use the following command:
em_compose_oc className
Note If you find errors in this step, you can often get additional error details by using the oammsg* and mdr* tracing flags with the em_debug utility.
4. Load name bindings.
- Use the load name binding utilities to load the defined name bindings in the platform. This detects possible errors in the name binding or naming attribute. Use the following command:
em_load_name_bindings Namebinding- Repeat this for all name bindings specified in the GDMO definition for the object class.
Note If you find errors in this step, you can often get additional error details by using the oammsg* and mdr* tracing flags with the em_debug utility.
5. Create an instance.
- Use OBED or a simple PMI program to create an instance of the MOC. This ensures that the GDMO/ASN.1 definitions are correct and that all CMIP operations can be performed. After you verify this, use OBED or the PMI program to delete the instance.
6. Restore ACTION definitions in GDMO.
- Remove the comments to the ACTIONS in the GDMO definition for the MOC. You should now be ready to use ODT.
7. Remove old definitions and prepare to load new object.
- Run em_services -reload to reinitialize the MDR and MIS. Follow the object development process (see Section10.3 Object Development Overview") to load your new implementation.
10.4 Object Code Generator Utility
The Object Code Generator utility (OCG) provides a set of C++ classes and methods that you use can to implement the behavior for managed objects defined in GDMO. The OCG is external to the MIS. The code generated and the user-defined implementation reside in a dynamic shared library linked to the MIS.
The OCG generates the C++ stubs for attribute access, instance access, and action access for the class. You fill in the behavior in the stubs. The utility hides the process by which user-defined behavior is connected to the framework. In other words, you only change code stubs for:
- Attribute access (CMIP GET and SET)
- Action access (CMIP ACTION)
- Instance access (CMIP CREATE and DELETE)
- Notification emission (CMIP NOTIFICATION)
- Discriminator-match stub to implement behavior when a discriminator matches, if the user includes the discriminator package in the class definition.
The generated code also contains debugging information to help you trace what happens at run time.
Note The Solstice EM MIS must be running locally to generate implementation.
10.4.1 Generated Code Interfaces
The generated code interface provides a set of generated code stubs that can be used to invoke user developed object behavior functions. The interfaces and underlying code are produced by the OCG, which operates on information in the meta data repository (MDR) and on information in a configuration file. The GDMO and ASN.1 definitions for GDMO object need to be loaded into the MDR prior to generating the code and interfaces.
The Object Behavior Interface is shown in FIGURE 10-2, with the generated code interface highlighted:
FIGURE 10-2 ODT Framework, with Generated Code Interface Highlighted![]()
10.4.2 Code Generation Components
FIGURE 10-3 shows the components involved in the agent role behavior code generation portion of the Object Behavior Interface. The OCG generates the appropriate agent role behavior code and code stubs for the GDMO-defined managed object class based on the GDMO definition loaded into the MDR and on parameters you specify in a configuration file.
The OCG also generates a PMI client create program that you can use to instantiate an instance of the new managed object class.
FIGURE 10-3 Code Generation Components10.4.2.1 Inputs
The Object Code Generator utility takes input from the following sources:
- GDMO and ASN.1 files containing the class descriptions
- Configuration file
10.4.2.2 Outputs
The Object Code Generator utility provides the following output:
- C++ code stubs for attribute access, actions access, and instance access
- The stub for attribute access allows you to add behavior for each attribute when a CMIP GET/SET is done.
- The stubs for action access allow you to add behavior for each action supported by the GDMO class definition.
- The stubs for instance access allow you to add behavior to be executed when CMIP CREATE/DELETE operations are done.
- Code that links the object implementation to the framework
- This is called the annotation code. Object implementors should not change any of this code. The annotation OID is unique and is generated automatically.
Note All the attributes and the object instance are either persistent or volatile. You control volatility on a per-object class basis.
- Makefile that generates an object implementation (shared library)
- Utilities to load and unload object implementation dynamically
- If a GDMO object class has notification definitions, you need to add specialized behavior code to specify when the event should be generated. To do this, you use the SendEventReportRequest function provided by the Object Services API (OSAPI).
- GDMO Inheritance is supported. This means behavior defined for a superior class is re-used transparently when generating code for a derived class. You cannot override any behavior inherited from the superior class.
10.4.3 Using the Object Code Generator Utility
Before you use the OCG, you must compile the GDMO and ASN.1 definitions using the GDMO and ASN.1 compiler and restart MIS to load the GDMO and ASN.1 definitions. You then have the following options for the object behavior:
- Default behavior with persistence
- Default behavior with volatile attributes
- Non-default (user-specified) behavior with persistence
- Non-default (user-specified) behavior with volatile attributes
The OCG is a command line function. To run it, use the following command:
% $EM_HOME/bin/em_obcodegen -help filename
Note $EM_HOME is an environment variable used to designate the directory in which Solstice EM is installed, typically /opt/SUNWconn/em.
TABLE 10-1 OCG Command Line Options -help Displays a list of command options. filename td> Identifies the class name to generate code for. The GDMO and ASN.1 files must match this file name.
TABLE 10-1 identifies the options available for em_obcodegen.Example
To generate code for the chai example, you would use the following format:
% $EM_HOME/bin/em_obcodegen chai10.4.4 Configuring the Object Code Generator Utility
The specific code the OCG generates depends on a number of configuration parameters. You can define these parameters in any of the following locations:
- In your login shell as user-specific environment variables
- In a local configuration file called EM_obcodegen.cfg
- In the global configuration file /etc/opt/SUNWconn/em/conf/odt/EM_obcodegen.cfg
If several developers need to use a standard configuration, use the global configuration file. TABLE 10-2 lists the parameters you can define for ODT configuration.
10.4.5 How Filter Attributes Affect Code Generation
The GDMO definition for your object class can include following three attributes that affect how code is generated for receiving events:
- DiscriminatorConstruct
- OperationalState
- AdministrativeState
If these attributes exist in your GDMO definition and FILTER_ATTR is set to DiscriminatorConstruct, then OCG generates the following code:
receive_event(EventType, EventInfo);If FILTER_ATTR is set to DiscriminatorConstruct and any of these attributes are not defined in your GDMO, then you see a warning message and this line of code is not generated.
10.5 Implementing GDMO Specified Object Behavior
There are 5 important operational aspects to the Generated Interfaces the ODT user must understand:
- MIS object modeling concepts
- Asynchronous interface behavior
- Use of the subfetch, subread, subwrite and substore interfaces
- Propagation of errors
- Serialization of object requests
10.5.1 MIS Object Modeling Concepts
Solstice EM defines object behaviors according to the abstractions described in TABLE 10-3 .
TABLE 10-3 Behavior Abstractions Instantiation object creation and deletion Containment management of children Attribute Management storage/access to attributes Actions action behavior
These four areas have C++ base classes that define interfaces for the functionality listed above. The base C++ classes that implement these behaviors are known collectively as Secretaries. A Secretary is a named component of code that implements a specific functionality. New object behaviors are added to the MIS framework by describing to the MIS the set of secretaries (components of behavior) that will implement the behaviors for a particular GDMO Object Class. This description is called the Object Behavior Definition (OBD). The OBD is a list of the secretaries and is automatically generated by the ODT and is hidden from the ODT user.
The framework by default provides for instantiation, containment, attribute and action support of agent role behavior. The ODT user need only insert behavior code at well defined interfaces to supplement or augment these default behaviors.
New behaviors are created by deriving new C++ object classes from the base C++ secretary classes. The ODT generates these derived classes on behalf of the user for a specific GDMO Managed Object Class. To simplify the problem of creating agent behaviors the ODT has exposed the interfaces listed below.
The following list summarizes the functions or points in the generated code that can be modified by a user of the Object Behavior Interface. For most objects, you will not need to supply additional code for every interface point listed here:
- Attribute secretary read function: className_AttrSecty::read
- Attribute secretary write function: className_AttrSecty::write
- Attribute secretary read function: className_AttrSecty::fetch
- Attribute secretary write function: className_AttrSecty::store
- Action secretary check function: classNameActionSecty::action
- Action secretary perform function: className_InstanceSecty::create_vote
- Action secretary do not perform function: className_AttributeSecty::destroy_vote
- Dynamic Loader interface: className_loader
10.5.2 Asynchronous Interface Behavior
Asynchronous behavior is introduced at an interface by providing a callback parameter as part of the interface invocation. The expectation is that the implementor of the interface will only invoke the callback when the interface functionality is complete. Solstice EM provides the following asynchronous interfaces:
- fetch
- store
- action
These provide interfaces which allow the user an asynchronous interface to fetch data, store data and perform actions in an asynchronous manner. A callback is invoked by using the exec method:
cb.exec(parmarater);The parameter to the exec invocation is one of the ways used to indicate status to the invoker. For more information on this parameter, see Section10.5.4 Propagation of Errors".
The Object Framework uses a state machine model to manage the different phases to complete the different CMIS requests. These requests and the interfaces they invoke are described in TABLE 10-4 and TABLE 10-5 .
TABLE 10-4 lists the order of interfaces invoked for each CMIS request.
TABLE 10-5 Order of CMIS Request Interfaces M_GET fetch, read M_SET fetch, read, write, store M_CREATE write, store
At each phase the framework invokes the appropriate interface for all attributes in the CMIS request. An M_GET with an attribute list with two attributes will invoke fetch twice followed by 2 read requests. An M_SET for three attributes will invoke fetch for each of the three attributes, followed by a read for each of the three attributes followed by a write and a store for each of the listed attributes.
Consider the fetch interface as a simple example of how asynchronous behavior is achieved:
ClassName_AttrSecty::fetch(ai,callback)The invoker of this interface does not expect that when the fetch function returns that the attribute specified by ai has been fetched. The implementation may need to send a request to another entity or agent to fetch the attribute data. However, instead of waiting for the remote entity to respond, the fetch implementation can store the callback parameter and schedule its own callback for when the remote entity provides the attribute data.
On receipt of the attribute data, the fetch interface then invokes the stored callback, indicating to the originator of the fetch invocation that data is now available synchronously. In other words, you can pass a callback to subfetch which, when called, calls the original callback passed in fetch. The invoker can then invoke the ClassName_AttrSecty::read synchronously.
Similarly for storage operation, the ClassName_AttrSecty::store function is passed a callback. Only when the data has been stored should the implementor invoke the passed callback.
The Solstice EM Object Framework invokes the generated Object Behavior Interfaces fetch, read, write and store in a particular order depending on the CMIS request being performed. These interfaces are designed to allow asynchronous requests to be satisfied. The fetch, store and action interfaces are all asynchronous interfaces. FIGURE 10-4 outlines the normal order of operations for a GET request. The framework calls the UserSecty code fetch function for all attributes providing as parameters the attribute identifier and the callback to be invoked when the fetch has been completed. The fetch code is responsible for fetching the attribute data from wherever it is stored.
Once the data has been fetched the UserSecty code must then call the callback provided. The framework maintains a count of all the outstanding callbacks. When all callbacks have been received, the framework enters the read phase. The assumption is that since the (asynchronous) fetch has completed, the (synchronous) read can complete without blocking. Remember that read and write are synchronous operations for accessing memory, while fetch and store are asynchronous and act on disk storage.
In the sequence diagrams below, half arrows indicate asynchronous operations and full arrows denote synchronous operations.
FIGURE 10-4 Sequence Diagram for M_GET operationFIGURE 10-4 indicates the normal flow for the code that is generated by the ODT. In particular it is important to understand that the subordinate operations do not need to be called unless default behavior is desired. However, once a subordinate fetch function is called, the subsequent read on the fetch attribute should also call the subread function. The use of the sub functions is detailed in the sub operation section following.
The diagrams below outline the sequence flow for M_ACTION and M_SET operations.
FIGURE 10-5 Sequence Diagram for M_ACTION FIGURE 10-6 Sequence Diagram for M_SETIt is important for the ODT interface implementor to obey the rules of the interface. Essentially the implementor must issue a callback for every asynchronous received. Failure to do so will cause the original request to be suspended. The MIS will continue to operate and service other requests
The default behavior for fetch and store is that the callback is executed immediately from the fetch and substore operations. If the ODT developer does not wish to use this default behavior and decides to delay the invocation of the fetch or store callback the ODT developer must register the object class implementation with the OamAsyncable Interface. To register an object class in the OamAsyncTableIf the oamasynctblif::AppendAsyncTBl method is used:
oamasyntblif::AppendAsyncTbl(Oid("1.2.3.4.5.6.7", TRUE);This registers Object Class 1.3.4.5.6.7 as an asynchronous class.
Note Failure to register the Object Class as asynchronous may result in random MIS code dumps.
10.5.3 Sub Operations: subfetch, subread, subwrite, substore
The interfaces subfetch, subread, subwrite, and substore are used to interface to a service layer coupled to the UserSecty code via a late binding mechanism in the MIS framework. The services currently offered in this manner are Volatile and Persistent. Volatile refers to an in-core storage mechanism for managed objects. Persistent refers to the persistent service component of Solstice EM. Volatile or persistent behavior is defined by configuration. See Section 12.5.6 "Configuring the Object Code Generator" for information on how to configure for volatile or persistent behavior. By obeying the conventions of the sub operations an object class implementation can be switched easily from volatile to persistent.
To use the volatile or persistent services the ODT developer must invoke the sub operations. The rules that apply to the fetch, read, write and store interface apply again. The semantics are the same.
The invocation of sub operations are not mandatory. However the rules of the interfaces must be obeyed. Subfetch must always be called before subread. Subread cannot be called until the callback passed to subfetch has been invoked. Subwrite must always be called before substore. Data is not deemed to be stored until the substore callback has been called.
The default code generated by ODT for fetch is to call subfetch. The subfetch code then invokes the original invoker's callback. If you pass a different callback to subfetch, it must call the original callback to fetch. If the ODT developer chooses not to call the subfetch function then the ODT developer assumes responsibility for invoking the callback supplied as an argument to the fetch call.
A user may choose to only use persistence for a write through capability. In this case the ODT developer would only need to use subwrite and substore. Once data has been stored to persistence using the subwrite and substore interfaces, the user may subsequently use subfetch and subread to retrieve the data.
10.5.4 Propagation of Errors
The ODT framework has three different means to reflect errors back to the request invoker:
- Return Value
- Solstice EM MIS Exceptions
- Operr Data Structure
The interface error mechanisms have been designed to allow for maximum flexibility while at the same time offering support to hide the complexity of building a CMIS error PDU. CMIP errors come in two flavors: List Errors and Fatal Errors.
List errors occur on M_SET and M_GET operations and indicate a partial error on a specific attribute or list of attributes. For example, an M_SET operation on an object containing AdminstrativeState and OperationalState would result in a SET_LIST_ERROR response since OperationalState is read-only. An attempt to create an instance of an unknown object class would result in a Fatal Error of NO_SUCH_OBJECT_CLASS.
The Object Framework determines the appropriate error for errors reflected by return value or exceptions. It builds the error PDU and issues the error response. The Operr mechanism allows for complete flexibility to indicate any type of error to the request invoker. The Operr mechanism is used at the fetch and store interfaces only.
Note The Operr method is the recommended means to generate errors for all operations.
10.5.4.1 Return Value
The Return Value is OK or NOT_OK. The specifics of which error an OK or NOT_OK produces is detailed in the sections specific to each interface.
10.5.4.2 MIS Exceptions
Exceptions are passed back across an interface by using the THROW or VTHROW macros. The specifics of which error is produced for an interface is detailed in the sections specific to each interface.
10.5.4.3 Operr Returns Values
The Operr class has four constructors which will construct different error responses. The types of error responses that can be constructed are:
- ANY CMIS Error Message
- Processing Failure with Specific Error
- Processing Failure with Probable Cause Oid Format
- Processing Failure with Probable Cause Integer Format
Operr(Message * ErrorMsgp);This will cause the MIS to send an error message, pointed by ErrorMsgp to the original requester. The error message is allocated using the Message::new_message method All fields must be completed in the Error Message.
Operr(Oid & errorId, Asn1Value &errorInfo);This will cause the MIS to send a ProcessFailure message to the original requester. errorId and errorInfo constitute the specific error part of that ProcessFailure message. The syntax for SpecificErrorInfo is:
SpecificErrorInfo ::= SEQUENCE {errorId OBJECT IDENTIFIER,errorInfo ANY DEFINED BY errorId}The errorId parameter must be a valid OID. The errorInfo must be a properly encoded Asn1Value as defined by errorId.
Operr(int OperrInt);This will cause the MIS to send a ProcessFailure message to the original requester. The specific error part of the message is set to probableCause (2.9.3.2.7.18) and the error number indicated by OperrInt.
Operr(Oid & OperrOid);This will cause the MIS to send a ProcessFailure message. The specific error part of the message is set to probableCause (2.9.3.2.7.18) and the error information indicated by OperrOid. In this case, the OperrOid must contain one of the valid OID defined in /SUNWconn/etc/gdmo/dmi.gdmo for probableCause.
To use the Operr format of error reporting the user must allocate an appropriate Operr instance on the heap and then pass it to a fetch or store callback:
Note Fetch and store are called for every attribute. The ODT developer must respond to every fetch and store by issuing a callback for every fetch and store received. The object framework examines these callbacks for errors but only uses the first error reported to generate the requested error response. It will discard any subsequent Operr responses.
Note The ODT developer must allocate the Operr Data Structure from the heap. The framework deletes the Operr structure when it no longer needs it. Operr data structures can only be used in fetch and store Callbacks. They must not be used for the ::Action result callback.
10.5.5 Serialization of Object Requests
To guarantee consistency within a managed object instance, the object framework employs a simple lock management scheme to lock the object for destructive operations. The locking mechanism locks an object exclusively for M_SET, M_CREATE, M_DELETE and M_ACTION requests. Exclusive locks enforce serialized access to the object and force an operation to complete before the next operation is allowed to start. M_GET requests are honored using a shared lock level, allowing multiple M_GETs to operate on the same managed instance concurrently.
The default lock mode for M_ACTIONs is LOCK_EXCL (exclusive). This mode requires that an action completes before any other operation can be started. Since M_ACTION requests are not necessarily destructive and may execute for a long time, the framework allows the ODT developer to set the lock mode that a specific M_ACTION may be executed at.
To override the default lock level for an action the ODT developer must set the desired action lock level using the oamlockif interface defined in oamlockif.hh. The function set_action_lock_level is used to set the action lock level. The following code example shows how to use the set_action_lock_level function:
Oid ActionOid("2.9.2.3.8.1");oamlockif::set_action_lock_level(ActionOid, OAM_LOCK_SHARE);The preceding code example sets the action defined by ActionOid to be shared. This will allow M_GETs and other shareable M_ACTIONs to be performed on the instance supporting these actions while an action is being executed. It will not allow M_SETs to be performed while any M_GETs to M_ACTIONs are in progress.
Note If M_GET operations seem to block indefinitely and the object implementation supports long running actions set the action level appropriately.
10.6 Debugging Objects
10.6.1 Process
1. Find out the process identifier of the running MIS.
hostname% ps -eaf | grep mis2. Run the debugger against the process identifier of the MIS.
hostname% debugger - MIS_pid_from_previous_step
3. When the debugger comes up, go to the debugger line and open the file className_user.cc. This should look similar to the following:
(debugger) file chai_user.cc4. Set a breakpoint in the className_user.cc file.
(debugger) stop in wherever5. Continue.
(debugger) cont10.6.2 Dynamic Loading in Solstice EM
OCG generates a default object implementation for a MOC defined using GDMO and ASN.1 and loaded in the MDR. Application developers can modify the default object implementation. The object implementation is built as a shared library that is loaded dynamically into the MIS at startup (em_services). Similarly, object implementations can be unloaded dynamically at MIS startup.
ODT provides two utilities that are generated as part of OCG:
- className.load installs the shared library and adds it to the system configuration file that MIS reads to load the object implementation.
- className.unload removes the shared library and removes it from the system configuration file that MIS reads to unload the object implementation.
Because the object implementations are loaded at different address spaces in the MIS when the MIS is started, an application developer cannot set a breakpoint at a well-known location in the dynamically loaded shared library. To enable users to debug object implementation, em_mis provides a well-known breakpoint that you can use before providing other breakpoints in the dynamically-loaded object implementation.
10.6.3 ASN.1 and GDMO Debugging
Solstice EM does not provide specific tools for debugging ASN.1 and GDMO files. For complete information on these syntax definitions, see the following:
- ITU X.208 ISO/IEC 8824, Specification of Abstract Syntax Notation One (ASN.1)
- ITU X.209 ISO/IEC 8825 Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1)
- ITU X.722 ISO/IEC 10165-4, Information Technology--Open systems Interconnection - Structure of Management Information--Part 4: Guidelines for the Definition of Managed Objects (GDMO)
10.6.4 Printing ASN.1 Values in Human-Readable Form
To print ASN.1 values (information in Asn1Value form) in human-readable form, first define the following in your .cc file:
Debug_on (className_info);Asn1Value av;Then, use the print method of Asn1Value defined in the PMI (asn1_val.hh) as follows:
av.print(className_info);
- Debug_on(className_info) is already generated by OCG in className_user.odt.cc.
- Debug_on(className_info) defines a Debug agent (className_info) that can be enabled or disabled at runtime or at compile time by using Debug_off, which turns off the agent.
10.6.5 Debugging Flags
OCG generates debug agents (className_error and className_info) for every object class. If you specify OBAPIDEBUG as YES in the configuration file, OCG enables these agents at compile time. To enable or disable these agents at runtime, use em_debug and the following commands:
- em_debug -c "on className_info" to enable agent at runtime
- em_debug -c "off className_info" to disable agent at runtime
- em_debug -c "on className_*" to enable all debug agents for className at runtime
When debugging behaviors that require you to use Object Services API (for example, if implementing inter-object behaviors), you can enable or disable debug agents specifically for Object Services API calls. To enable these agents, use the "objsvc_*" options for the em_debug utility as follows:
$EM_HOME/bin/em_debug -c "on objsvc_test$EM_HOME/bin/em_debug -c "on objsvc_errorOr use the following command:
$EM_HOME/bin/em_debug -c "on objsvc_*"To disable these agents, use em_debug -c "off objsvc_*."
10.7 Generated Files
If you have created valid GDMO and ASN.1 definition files and loaded them into the MDR, when you run OCG it creates the files in the target directory specified in your configuration file:
- Makefile.className
- README.className
- className_user.odt.cc
- className_user.odt.hh
- pmi_className.cc
- className.load
- className.unload
For complete examples of each of these files, see Section10.10 Object Development Scenario Using Chai Object."
10.7.1 Makefile (Makefile.className)
You use the Makefile to create ("make") a dynamic linked library for every object class for either default or user-extended implementation.
10.7.2 Readme File (README.className)
The README file explains how to use the files generated by OCG.
10.7.3 User Header File (className_user.odt.hh)
This header file contains the class definitions for the object class className. OCG generates definitions for the Attribute class, Action class, and Instance class. The Attribute and Action classes contain several helper methods that can be used to access other attributes or actions defined in this file or to perform read/write actions on other attributes or actions defined in this file, while implementing specific behavior for a given attribute or implementing a specific action.
In addition to the class definitions, the user header file defines Action indices, Attribute indices, and OIDs for Attributes, Actions, and Name Bindings.
Note You are not allowed to modify this file directly. The default object implementation build uses this file, so changes made to it will cause unpredictable results.
To add function prototypes or members in the header file, copy this file to className_user.hh and add your code there.
TABLE 10-6 identifies the Attribute classes OCG defines in this file:
TABLE 10-7 identifies the Action classes OCG defines in this file:
10.7.4 PMI Client Create Program for Object Instantiation (pmi_className.cc)
The PMI client create program file contains PMI client application code that is used to instantiate an instance of the new object class after the dynamic library for the new object class has been linked into the MIS.
10.7.5 User Code File (className_user.odt.cc)
The C++ source file contains the user-level methods defined for Attribute, Action, and Instance classes. The user function stubs that OCG generates include: read, write, fetch, store, action, create_vote, and destroy_vote. In addition, OCG generates a stub for receive_event if discrimination service is used.
Note You are not allowed to modify this file directly. The default object implementation build uses this file, so changes made to it will cause unpredictable results.
To add user-defined behaviors, copy this file to className_user.cc and add your code in the insertion areas clearly identified.
When implementing intra-object behaviors, you should use only the helper methods defined in Attribute, Action, and Instances classes. When implementing inter-object behavior, you should use the Object Services API calls as needed for behavior implementation.
10.7.6 Dynamic Loading File (className.load)
When you run this utility, the object implementation build is loaded into the platform as a shared library. The new object implementation is read at MIS startup.
10.7.7 Dynamic Unloading File (className.unload)
When you run this utility, the object implementation is removed from the platform. The object implementation is not read at MIS startup.
10.8 TRY Exception Macros
The development environment of Solstice EM includes some exception-handling macros that are used in cases where the C++ compiler does not handle the exception. These exception-handling macros are known as TRY macros. The basic elements of the TRY macros are the TRY block and the Handler block.
10.8.1 Overview
The TRY block brackets the code from which you want to receive exceptions. It must be followed immediately by a Handler block in which you specify how to handle the exception.
Exceptions are scoped dynamically. What this means is that a TRY block establishes a new exception context. When you exit the TRY block, you return to the previous exception context.
10.8.2 Code Structure
The basic structure of a TRY exception is as follows:
TRY {
some block of code that may generate exceptions
} BEGHANDLERS
CATCH macros that handle various exceptions
ENDHANDLERS10.8.3 Code Examples
The following example from the chai scenario shows how the TRY macros are used in the generated code:
TRY
{
// Fetch attribute specified by (ai)
return subfetch(ai,cb); }
BEGHANDLERS
CATCHALL { #ifdef ODT_DEFAULT
return (NOT_OK);
#endif }
ENDHANDLERS
}10.9 Object Development Examples
Solstice EM comes with several examples that illustrate how to develop object behaviors. All of these examples are located in the $EM_HOME/src/odt directory. This directory includes a README file that explains how to build the examples.
TABLE 10-8 identifies the examples and provides a brief description of what each one includes. A complete scenario that illustrates how to develop an object is included in Section10.10 Object Development Scenario Using Chai Object."
10.9.1 Compiling All Examples
You can compile and run the object behavior samples shipped with Solstice EM individually or as a group. Instructions for running each of the individual samples are provided in Section10.9.2 cellSample" through Section10.9.6 diskInfo." In addition, Section10.10 Object Development Scenario Using Chai Object" leads you through the entire process for the chai object in detail.
ODT provides a global Makefile that compiles all the object behavior examples. To build these examples, perform the following commands:
hostname# cd $EM_HOME/odt/src
hostname# Make all
Note This mechanism does not currently compile the cellSample example. You must compile and run cellSample by itself.
10.9.2 cellSample
10.9.2.1 Important Code Functions
The cellSample example illustrates how to use the Object Services API. Specific sections of the code are not specifically identified as being more important than any others. You might want to look at all the code to see how the Object Services API can be used effectively.
To Build the Example
1. Go to the ODT examples directory.
hostname% cd $EM_HOME/src/odt/cellSample2. Copy the cellSample GDMO and ASN.1 files to the appropriate directories.
hostname% cp cellSample.gdmo $EM_HOME/etc/gdmo
hostname% cp cellSample.asn1 $EM_HOME/etc/asn13. Load the GDMO into the MDR.
hostname% em_services -r4. Generate the code for cellSample.
hostname% em_obcodegen cellSample5. Create the dynamic linked library for the cellSample object class for default implementation.
hostname% make -f Makefile.cellSample extended6. Load the cellSample source into an addressable location in the MIS.
hostname% ./cellSample.load7. Restart the MIS.
hostname% $EM_HOME/bin/em_servicesTo Execute the Example
1. Create an instance of the cellSample object (instantiate the class).
./cellSample2. Start OBED and run actions against the cellSample.10.9.3 demoPing
10.9.3.1 Important Code Functions
The demoPing example shows how you can develop a simple native agent using the ODT.
Action Implementation
demoPing Callback Function
To Build the Example
1. Go to the ODT examples directory.
hostname% cd $EM_HOME/src/odt/demoPing2. Copy the demoPing GDMO and ASN.1 files to the appropriate directories.
hostname% cp demoPing.gdmo $EM_HOME/etc/gdmo
hostname% cp demoPing.asn1 $EM_HOME/etc/asn13. Load the GDMO into the MDR.
hostname% em_services reload4. Generate the code for demoPing.
hostname% em_obcodegen demoPing5. Create the dynamic linked library for the demoPing object class for default implementation.
hostname% make -f Makefile.demoPing extended6. Load the demoPing source into an addressable location in the MIS.
hostname% ./demoPing.load7. Restart the MIS.
hostname% $EM_HOME/bin/em_servicesTo Execute the Example
1. Create an instance of the demoPing object (instantiate the class).
./pmi_demoPing2. Start OBED and run action on instance specifying the hostname you want to ping.3. Alternatively, you can run the ODT Sample Program driver (odtsamples) and select the Ping option.10.9.4 demoregistry
10.9.4.1 Important Code Functions
Action Implementation
Function to Register Application
Function to Unregister Application
To Build the Example
1. Go to the ODT examples directory.
hostname% cd $EM_HOME/src/odt/demoregistry2. Copy the demoregistry GDMO and ASN.1 files to the appropriate directories.
hostname% cp demoregistry.gdmo $EM_HOME/etc/gdmo
hostname% cp demoregistry.asn1 $EM_HOME/etc/asn13. Load the GDMO into the MDR.
hostname% em_services reload4. Generate the code for demoregistry.
hostname% em_obcodegen demoregistry5. Create the dynamic linked library for the demoregistry object class for default implementation.
hostname% make -f Makefile.demoregistry extended6. Load the demoregistry source into an addressable location in the MIS.
hostname% ./demoregistry.load7. Restart the MIS.
hostname% $EM_HOME/bin/em_services10.9.4.2 Running the Example
1. Create an instance of demoregistry class (instantiate the class).
./pmi_demoregistry2. Run demo_server on your local host or, if running on a remote host make sure Solstice EM is installed on the remote host.3. Start OBED and find the object instance under EM-MIS.4. Click on the OI and issue a DemoReg action where the ActionInfo parameter is {"hostname", "ApplicationName", 345}.5. Alternatively, you can run the ODT Sample Program driver (odtsamples) and run the Register option or the UnRegister option.10.9.5 demoServer
10.9.5.1 Building the Example
1. Go to the ODT examples directory.
hostname% cd $EM_HOME/src/odt/demoServer2. Create the dynamic linked library for the demoServer object class for default implementation.
hostname% make10.9.5.2 Running the Example
To start the demo_server:
> demo_server10.9.6 diskInfo
10.9.6.1 Building the Example
1. Go to the ODT examples directory.
hostname% cd $EM_HOME/src/odt/diskInfo2. Copy the diskInfo GDMO and ASN.1 files to the appropriate directories.
hostname% cp diskInfo.gdmo $EM_HOME/etc/gdmo
hostname% cp diskInfo.asn1 $EM_HOME/etc/asn13. Load the GDMO into the MDR.
hostname% em_services reload4. Generate the code for diskInfo.
hostname% em_obcodegen diskInfo5. Create the dynamic linked library for the diskInfo object class for default implementation.
hostname% make -f Makefile.diskInfo extended6. Load the diskInfo source into an addressable location in the MIS.
hostname% ./diskInfo.load7. Restart the MIS.
hostname% $EM_HOME/bin/em_services10.9.6.2 Running the Example
1. Create an instance of the diskInfo object (instantiate the class).
./pmi_diskInfo2. Start OBED and run an action on the object instance, specifying the hostname about which you want to get disk information.3. Alternatively, you can run the ODT Sample Program driver (odtsamples) and select the DiskInfo of a Host option.10.10 Object Development Scenario Using Chai Object
The sample files shipped with Solstice EM for object development scenarios provide important information in README files. Although the information in the README files is fairly complete, this section of the documentation provides an expanded view of the object development scenario for the Chai managed object.
10.10.1 Creating Your Own Object Class
1. Load the chai managed object into the Meta Data Repository (MDR).
# em_gdmo hostname chai.gdmo
# em_asn1 -o `pwd' chai.asn1
# cp 1.3.6.1.4.1.42.2.2.2.1.96.3.1 /var/opt/SUNWconn/em/usr/data/ASN1
# cp *-ASN1 /var/opt/SUNWconn/em/usr/data/ASN12. Define environment variables, if needed.
- Location of hidden/intermediate files:
HIDDENDIR=/tmp- Data storage for OC whether PERSISTENT or VOLATILE:
DATASTORAGE=PERSISTENT3. Go to the directory where you want your code to be generated.
% cd user_directory4. Generate the C++ code for your objects.
- You will see output similar to the following:
- Note that OCG identifies the attributes, actions, and name bindings for which code will be generated.
- The following files are generated:
5. Compile and make the dynamic library for the default implementation.
% make -f Makefile.chai default
- This command compiles and makes a dynamic library called chai.so.
6. Create a customized implementation.
- To create a customized implementation, you need to first modify the source code. Then, to compile and make a customized library, use the following format:
% make -f Makefile.chai extended7. Load the new dynamic library.
% chai.load8. Terminate and restart the MIS.
# em_services9. Instantiate the new chai object.
% cd chai_Create_program
% make chai
% chai // This creates the chai object
% chai -g // This gets attributes of new chai object10. Run the debugger to verify the object behaves as expected.
% debugger $EM_HOME/bin/em_mis &
stop in DynLoader::DynLoader
run10.10.2 Debugging Flags
The following code lines that contain the debug agents for the chai object class are included in the chai_user.odt.cc file.
Debug_on(cahi_info)
Debug_on(chai_error)If debug agents are spread across multiple files, the above definitions must only be included in the chai_user.hh file (copied and modified from chai_user.odt.hh). The other files need to contain the following code lines:
extern Debug chai_info;
extern Debug chai_error;10.10.3 Sample Behavior Implementation
The following program implements specialized behavior for the chaiReady attribute. If chaiReady is 0, then set the chaiBlend to "Earl Grey" and send brewAction.
To add this behavior, insert the following piece of code in chai_user.cc at the location of chai_AttrSecty::read after the subread is performed.
10.10.4 chai Object Class Definitions
The example GDMO and ASN.1 definitions for the chai object class are installed into the $EM_HOME/src/odt/chai directory when you install the ODT onto your system (SUNWemobj package).
The chai.gdmo file defines the following attributes:
- chaiKettleNumber
- chaiBlend
- chaiReady
The chai.gdmo file also defines the brewChai action.
10.10.4.1 Sample chai.gdmo Definitions File
10.10.4.2 Sample chai.asn1 Definitions File
10.10.5 Sample PMI Program to Create a New chai Object Instance
10.10.6 Example Generated Code in .cc File
The following generated code stub examples are based on the chai example object. A complete scenario for defining the chai object is provided in Section10.10 Object Development Scenario Using Chai Object." The actual code that OCG generates can contain additional comments not reflected in this book.
Note Throughout these examples and in any code generated by OCG, there are lines that are similar to the following:
//********** $ODT_EXT_START [LOCAL VARIABLE INSERT] ************//
//********** $ODT_EXT_END [LOCAL VARIABLE INSERT] ************//
These lines indicate areas in the code where you can safely add your own code to the generated code to further customize object behaviors.
10.10.6.1 Generated Asynchronous Read Stub Function (FETCH)
Function
chai_AttrSecty::fetch (Const AttrSectyInfo &ai, Const callback&cb)Description
This function is an asynchronous interface for reading attributes. For every attribute requested in a GET or SET request, the MIS Framework calls fetch for that attribute, followed by a read of the same attribute. The fetch function can reflect status back to the invoker by:
- Using the return value from the function
- Throwing an MIS exception
- Passing a parameter to the invocation of the callback
Arguments
This function uses the following arguments:
- ai indicates the attribute to be read
- cb identifies the callback routine passed by Framework
Return Value
This function returns the following values:
- OK if the attribute is fetched and read successfully
- NOT_OK to indicate failure in fetching/reading attribute specified by ai
Errors
- NOT_OK
- SET_LIST_ERROR or GET_LIST_ERROR
- MIS Exceptions
- Any exception results in an SET_LIST_ERROR or a GET_LIST_ERROR. If an exception is thrown the callback must not be invoked
- Operr(ErrorMessage)
- Operr(intval)
- Operr(probableCauseOid);
- Operr(errorId, errorValue)
The Operr data structure is passed to the Object Framework by invoking the passed exec with the parameter set to a pointer to the allocated Operr data structure. The default behavior is for the subordinate secretary to invoke the callback.
Note A NULL parameter to the invocation of the callback indicates a POSITIVE status e.g cb.exec((Ptr) 0); If the ODT developer wishes to return an error, an Operr Data structure must be allocated from the heap and passed to the callback function.
Code Example
10.10.6.2 Generated Asynchronous Write Stub Function (STORE)
Function
chai_AttrSecty::store (Const AttrSectyInfo &ai, Const callback&cb)Description
This function is an asynchronous interface for storing attributes. For every attribute requested in a SET request, MIS Framework calls write for that attribute, followed by a store of the same attribute. The store function can reflect status back to the invoker by:
- using the return value from the function
- throwing an MIS exception
- passing a parameter to the invocation of the callback
Arguments
This function uses the following arguments:
- ai indicates the attribute to be stored
- cb identifies the callback routine passed by Framework
Return Value
This function returns the following values:
- OK if the attribute is written and stored successfully
- NOT_OK to indicate failure in writing/storing attribute specified by ai
Errors
- NOT_OK
- SET_LIST_ERROR
- MIS Exceptions
- Any exception results in a Process Failure If an exception is thrown the callback must not be invoked
- Operr(ErrorMessage)
- Operr(intval)
- Operr(probableCauseOid);
- Operr(errorId, errorValue)
The Operr data structure is passed to the Object Framework by invoking the passed exec with the parameter set to a pointer to the allocated Operr data structure. The default behavior is for the subordinate secretary to invoke the callback.
Note A NULL parameter to the invocation of the callback indicates a POSITIVE status e.g cb.exec((Ptr) 0); If the ODT developer wishes to return an error, an Operr Data structure must be allocated from the heap and passed to the callback function.
Code Example
10.10.6.3 Generated Synchronous Read Stub Function (READ)
Function
chai_AttrSecty::read (Const AttrSectyInfo &ai, Asn1Value &av)Description
This function is a synchronous interface for reading attributes. For every attribute requested in a GET or SET request, MIS Framework calls read for that attribute. The read function can reflect status back to the invoker by:
- using the return value from the function
- throwing an MIS exception
Arguments
This function uses the following arguments:
- ai indicates the attribute to be read
- av identifies the Asn1Value of the attribute read (output parameter)
Return Value
This function returns the following values:
- OK if the attribute is read successfully
- NOT_OK to indicate failure
Errors
- NOT_OK
- SET_LIST or GET_LIST Error
- MIS Exceptions
- All exceptions result in a SET_LIST or GET_LIST Error except in the case of a Resourcelimx exception which generates a ResourceLimit Error.
Code Example
10.10.6.4 Generated Synchronous Write Stub Function (WRITE)
Function
chai_AttrSecty::write (Const AttrSectyInfo &ai, Const Asn1Value&av)Description
This function is a synchronous interface for writing attributes. For every attribute requested in a SET request, MIS Framework calls write for that attribute. The write function can reflect status back to the invoker by:
- using the return value from the function
- throwing an MIS exception
Arguments
This function uses the following arguments:
- ai indicates the attribute to be written
- av identifies the Asn1Value of the attribute written (output parameter)
Return Value
This function returns the following values:
- OK if the attribute is written successfully
- NOT_OK to indicate failure
Errors
- NOT_OK
- SET_LIST or GET_LIST Error
- MIS Exceptions
- All exceptions result in a ProcessFailure.
Code Example
10.10.6.5 Generated Action Stub Function (ACTION)
Function
chai_AttrSecty::action (Const AttrSectyInfo &ai, Const Asn1Value&input, Const callback &cb)Description
This function is an asynchronous interface for handling CMIP ACTIONS. The CMIP actions handled are those specified in the Managed Object Class definition in the GDMO. The action stub function can issue status to the invoker using 2 methods:
- Throwing an MIS Exception
- As a Parameter to the Callback
Arguments
This function uses the following arguments:
- ai indicates the action
- input indicates the Asn1Value specified by the user through the INFORMATION SYNTAX clause in the GDMO ACTION definition
- cb identifies the callback routine passed by Framework to process cb.exec (CheckData) where CheckData contains the returned ACTION RESPONSE and ACTION RESULT
Return Value
This function returns no values aside from those passed back in the cb argument. CheckData return values are:
- If Operation completed successfully
- If Operation terminated with an error the developer has 2 options
- Throw an MIS exception which will result in a ProcessingFailure. The callback need not be invoked
- Use the Checkdata Structure to indicate the error. Set cd.result to CHECK_ERROR and fill in cd.error with an Error Response Message. If cd.error is not set the framework will issue a processing failure error.
Sample Error Generating Code
The following code illustrates how to build an Action Response message. The action_type Oid is found in the ai and needs to be encoded using CONTEXT(2) as the tag. The object instance and object class information can be found from the moi reference. The action_reply is an any defined by the action_type. This needs to be encoded according to the syntax of the action_reply_syntax:
The same method above could be used to create any response message defined in message.hh that would make sense for this action request.
Code Example
10.10.6.6 Generated Instance Create Stub Function (CREATE)
Function
chai_AttrSecty::create_vote (Const Asn1Value &fdn,Const Asn1Value &av)Description
This function lets you validate a CMIP CREATE request before the infrastructure creates the object instance. The function is passed a resolved attribute list and FDN, which you can validate before voting OK or NOT_OK.
Arguments
This function uses the following arguments:
- fdn is the FDN (Fully-Distinguished Name) of the object instance to be created.
- av identifies the Asn1Value of the resolved Attribute List.
Return Value
This function returns the following values:
- OK to go ahead and create the object instance.
- NOT_OK to not create the object instance.
Code Example
10.10.6.7 Generated Instance Destroy Stub Function (DELETE)
Function
chai_AttrSecty::destroy_vote()Description
This function lets you validate a CMIP DELETE request before the infrastructure deletes the object instance.
Arguments
This function uses no arguments.
Return Value
This function returns the following values:
- OK to delete the object instance.
- NOT_OK to not delete the object instance.
Code Example
10.10.6.8 Generated Receive Event Stub Function (RECEIVE_EVENT)
Function
chai_AttrSecty::receive_event (Asn1Value &event_type,Asn1Value &event_info)Description
This function lets you receive events and notifications specified in event_type and event_info. You would provide specialized processing depending on event_type and event_info which have been received as the discriminatorConstruct specified in the object instance.
Note The receive_event function only allow the user to access the event_type and event_info. This is a known problem. To access the complete event message place code in the invoke_moi function in the ObjectClassimpl.cc file which lives in the.hidden directory. In the cmd == discriminator_match section the developer can access the complete event message by casting parm to be an EventReq *. See example below.
Note This function is generated only if you specify the three discriminator attributes (DiscriminatorConstruct, OperationalState, and AdministrativeState) in your GDMO file and specify FILTER_ATTR: DiscriminatorConstruct in your configuration file.
Arguments
This function uses the following arguments:
- event_type is the type of event or notification received
- event_info is the Event Info received
Return Value
This function returns the following values:
- OK if the event or notification was processed successfully
- NOT_OK to indicate failure in processing event or notification
Code Example
10.10.7 Example Generated Code in .hh File
The chai_user.hh file contains class definitions required for implementing behaviors. The object framework uses the methods defined in this file to perform CMIS operations on the managed object instance. The following secretaries are defined in this file:
- chai_AttrSecty
- chai_ActionSecty
- chai_InstanceSecty
10.10.7.1 Generated Object Definitions
10.10.7.2 Generated OIDs
10.10.7.3 Attribute Class Definition
10.10.7.4 Action Class Definition
|
Sun Microsystems, Inc. Copyright information. All rights reserved. |
Doc Set | Contents | Previous | Next | Index |