| Solstice Enterprise Manager 4.1 Developing C++ Applications |
Performing Operations on Managed Objects
An application manages a network by monitoring and controlling managed resources in the network. In the EM environment, managed resources are represented as managed objects. An application monitors and controls managed resources by performing operations on managed objects. An application performs operations to add managed objects to and remove them from the network management environment; to get information about managed objects; and to change the state of a managed object.
This chapter explains how to enable your applications to perform management operations on managed objects.
- Section 5.1 Management Operations
- Section 5.2 Creating a Managed Object
- Section 5.3 Selecting a Managed Object
- Section 5.4 Updating an Image Instance
- Section 5.5 Deleting a Managed Object
- Section 5.6 Getting Attribute Values From an Object
- Section 5.7 Setting Attribute Values of an Object
- Section 5.8 Performing an Action on an Object
- Section 5.9 Tracking Changes to an Object
- Section 5.10 Retrieving Data From the Metadata Repository
- Section 5.11 Simulating an Agent Object
- Section 5.12 Representing MIS Instances Locally in an Application
5.1 Management Operations
The Solstice EM APIs are independent of any particular management protocol or service. When you use them to develop management applications, you do not need to take account of the protocol used for communications between the agent and the manager.
The Solstice EM APIs support management operations common to most network management environments, namely:
- Creating a managed object
- Deleting a managed object
- Getting attribute values from an object
- Setting attribute values of an object
- Performing an action on an object
5.2 Creating a Managed Object
To enable users of your applications to add a managed resource to the network, an application must create a managed object to represent the managed resource. The managed resource can be a physical device such as a host, server, router, or subnet, or it can be a conceptual entity such as a line, a queue, or some other aspect of network operation that can be represented as a managed object.
An application can create an object only if the specification of the managed object allows it to be created by a management operation. Specifically, the NAME BINDING clause of the GDMO specification of the managed object class must contain the CREATE construct. Otherwise, any request to create an instance of the class is denied.
To create a managed object, use the Image class. An instance of the Image class is a local representation of a managed object. A local representation is cached within your network management application.
An instance of Image gives you access to the methods and attributes of a managed object. It provides attribute-like access to object and attribute schema information. Although the actual managed object is in a management information server (MIS), or in an agent in the network, you can treat an instance of Image as if it is the managed object itself.
Creating a managed object involves:
- Creating and initializing an instance of Image
- Activating the instance of Image
- Verifying if the managed object exists
- Initializing attributes of the managed object
- Adding the managed object to the MIS
5.2.1 Creating and Initializing an Instance of Image
To create a managed object, an application must create and initialize an instance of the Image class. When you call the constructor of the Image class, you must specify:
- The fully distinguished name (FDN), local distinguished name (LDN), or nickname of the managed object that the instance of Image represents
- The managed object class that the managed object is an instance of
Code for creating and initializing an instance of the Image class is shown in CODE EXAMPLE 5-1.
In this example, the constructor of the Image class is called in the body of a function named create_channel. The Image object represents an instance of a managed object class named channel. The FDN of the channel managed object instance is constructed from information passed as parameters to the create_channel function:
- The FDN of the managed object that contains this instance of channel
- The value of the naming attribute of this instance of channel
5.2.2 Activating the Instance of Image
Activating an Image instance loads attribute information into the Image instance from a managed object in an MIS or an agent. Until an Image instance is activated, it represents a potential managed object. Once the Image instance has been activated, it represents and contains information from an actual managed object.
To activate an Image instance, call the boot function of the Image class. The effect of calling the boot function depends on whether the managed object that the Image instance represents already exists:
- If the managed object does not exist, calling the boot function retrieves the GDMO description of the managed object from the MIS.
- If the managed object already exists, calling the boot function retrieves the GDMO description and the values of all the attributes of the managed object from the MIS.
The boot function is an overloaded function of which there are two versions. One version takes an attribute list as a parameter. The other version does not take an attribute list as a parameter. To ensure that the boot function loads information on all attributes defined for the managed object, call the version of boot that does not take an attribute list.
Note A call to boot will fail if the identity of the managed object is invalid for the managed object class specified in the call to the Image constructor.
Code for activating an Image instance and checking for errors is shown in CODE EXAM PLE 5-2.
CODE EXAMPLE 5-2 Activating an Image Instance
... #include <pmi/hi.hh> // High Level PMI ...if (!channel_image.boot()) { cout << channel_image.get_error_string() << endl; return; } ...In this example, the overloaded NOT (!) operator acts on the call to boot to verify that the Image instance was activated. If it was not activated, an error message explaining the reason for the failure is displayed. To ensure that information for all attributes is loaded, the version of boot that does not take an attribute list is called.
5.2.3 Verifying if the Managed Object Exists
Verify if the managed object that the Image instance represents exists before trying to create it. If your application tries to create a managed object that already exists, an exception will be thrown. To verify if the managed object exists, call the exists function of the Image class.
Call the exists function only after you have activated the Image instance. If the Image instance has not already been activated, the exists function returns FALSE even if the managed object exists.
Code for verifying if a managed object exists is shown in CODE EXAMPLE 5-3.
CODE EXAMPLE 5-3 Verifying if a Managed Object Exists
... #include <pmi/hi.hh> // High Level PMI ...if (channel_image.exists()) { cout << "Channel already exists!" << endl; return; } ...In this example, the function that contains this code returns without taking any further action if the managed object exists.
5.2.4 Initializing Attributes of the Managed Object
If the managed object does not already exist, initialize its attributes. Make sure that:
- You initialize all mandatory attributes, that is all attributes that the GDMO specification of the managed object class requires to be initialized.
- The values you initialize the attributes to are allowed by the GDMO specification of the managed object class.
- You initialize only attributes that the GDMO specification of the managed object class allows to be initialized.
To initialize the attributes of the managed object, call functions of the Image class for setting attributes. The function you call depends on the type of the attribute as defined in the GDMO specification of the managed object class. For full details, refer to Section 5.7 Setting Attribute Values of an Object.
Check for errors each time you initialize an attribute. If a single attribute fails to be initialized, the creation of the managed object may fail. If you include error checking in each PMI call to initialize an attribute, you will know immediately why an attempt to create a managed object failed.
Code for initializing attributes of a managed object is shown in CODE EXAMPLE 5-4.
CODE EXAMPLE 5-4 Initializing Managed Object Attributes
... #include <pmi/hi.hh> // High Level PMI ...if (!channel_image.set_str("administrativeState","unlocked")) { cout << "Can't set administrativeState - "; cout << channel_image.get_error_string() << endl; return; }if (!channel_image.set_str("operationalState","enabled")) { cout << "Can't set operationalState - "; cout << channel_image.get_error_string() << endl; return; }if (!channel_image.set_long("transmitDelay",30)) { cout << "Can't set transmitDelay - "; cout << channel_image.get_error_string() << endl; return; } ...In this example, attributes of the managed object are initialized as follows:
- The set_str function sets the administrativeState attribute to the text unlocked.
- The set_str function sets the operationalState attribute to the text enabled.
- The set_long function sets the transmitDelay attribute to the value 30.
If an attempt to set an attribute fails, an error message is displayed to indicate which attribute was not set and why.
5.2.5 Adding the Managed Object to the MIS
After initializing attributes of the managed object, add the managed object to the MIS that you have connected your application to. For information on how to connect an application to an MIS, refer to Section 3.1 Connecting to an MIS. To add a managed object to an MIS, call the create function of the Image class.
Code for adding a managed object to an MIS is shown in CODE EXAMP LE 5-5.
CODE EXAMPLE 5-5 Adding a Managed Object to an MIS
... #include <pmi/hi.hh> // High Level PMI ...if (!channel_image.create()) { cout << "Creation failed: "; cout << channel_image.get_error_string() << endl; return;} else { cout << "Creation succeeded!" << endl; } ...In this example, the overloaded NOT (!) operator acts on the call to create to verify that the managed object was created. If it was not created, an error message explaining the reason for the failure is displayed.
5.2.6 Example Object Creation Function
An example of a function that contains all the code for creating a managed object is shown in CODE EXAMPLE 5-6.
CODE EXAMPLE 5-6 Example Object Creation Function
... #include <pmi/hi.hh> // High Level PMI #include <rw/cstring.h> // Rogue Wave RWCString ... void create_channel(RWCString parent, RWCString channel_name){ // Construct the distinguished name of the channel object RWCString fdn = parent + "/channelId=\"" + channel_name + "\""; cout << "Creating: " << fdn.data() << endl;Image channel_image(DU(fdn),DU("channel"));if (channel_image.get_error_type() != PMI_SUCCESS) { cout << channel_image.get_error_string() << endl; return; }if (!channel_image.boot()) { cout << channel_image.get_error_string() << endl; return; }if (channel_image.exists()) { cout << "Channel already exists!" << endl; return; }if (!channel_image.set_str("administrativeState","unlocked")) { cout << "Can't set administrativeState - "; cout << channel_image.get_error_string() << endl; return; }if (!channel_image.set_str("operationalState","enabled")) { cout << "Can't set operationalState - "; cout << channel_image.get_error_string() << endl; return; }if (!channel_image.set_long("transmitDelay",30)) { cout << "Can't set transmitDelay - "; cout << channel_image.get_error_string() << endl; return; }if (!channel_image.create()) { cout << "Creation failed: "; cout << channel_image.get_error_string() << endl; return;} else { cout << "Creation succeeded!" << endl; } } ...5.3 Selecting a Managed Object
When you perform a management operation on an existing managed object, you have to select the managed object in one of the following ways:
- Specifying the FDN or LDN of a managed object
- Specifying the nickname of a managed object
5.3.1 Selecting a Managed Object by Specifying its FDN or LDN
To select a managed object by specifying its FDN or LDN, create and initialize an instance of the Image class, specifying only the FDN or LDN. There is no need to specify the managed object class.
By specifying only the FDN or LDN of the managed object, you can verify if the managed object exists by testing if the attempt to instantiate the Image class was successful. If the FDN or LDN does not identify an existing managed object, the call to the constructor of the Image class fails.
Code for selecting a managed object by specifying its FDN is shown in CODE EXAM PLE 5-7.
CODE EXAMPLE 5-7 Selecting a Managed Object by Specifying its FDN
... #include <pmi/hi.hh> // High Level PMI #include <rw/cstring.h> // Rogue Wave RWCString ... Boolean delete_object(RWCString fdn){ Image del_image(fdn.data());if (del_image.get_error_type() != PMI_SUCCESS) { cout << del_image.get_error_string() << endl; return FALSE; } ... } ...In this example, the constructor of the Image class is called in the body of a function named delete_object. The FDN of the managed object is constructed from information passed as a parameter to the delete_object function. If the FDN passed to the constructor of the Image class does not identify an existing managed object, the function that contains this code returns FALSE.
5.3.2 Selecting a Managed Object by Specifying its Nickname
In an MIT with many levels of containment, FDNs become long and complicated, particularly the FDNs of managed objects that are many levels below the root of the MIT. To simplify the task of selecting managed objects, assign nicknames to managed objects and select managed objects by specifying their nicknames.
You are free to choose the nickname you assign to a managed object. Assigning short and memorable nicknames to managed objects reduces the possibility of coding errors and makes your code easier to read.
Selecting a managed object by specifying its nickname involves:
- Starting and configuring the nickname service
- Getting the Image instance associated with a nickname
In addition, the Image class provides functions for getting and setting the nickname of an Image instance.
5.3.2.1 Starting and Configuring the Nickname Service
The nickname service translates between nicknames and FDNs of managed objects. To enable your application to locate a managed object specified by its nickname, ensure that the nickname service has been started and configured before you run your application.
Starting and configuring the nickname service involves:
- Starting the nickname service daemon
- Adding the nickname service to the MIS
- Assigning nicknames to managed objects
- Loading nickname assignments into the nickname service
Starting the Nickname Service Daemon
The nickname service daemon (em_nnmpa) is started automatically whenever the MIS is started. To start the MIS, execute the em_services command. For more information, refer to the Management Information Server (MIS) Guide.
Adding the Nickname Service to the MIS
To enable an application to communicate with the nickname service, the nickname service must be added to the MIS. The MIS treats the nickname service as a management protocol adapter (MPA).
By default, the nickname service is added automatically to the MIS when Solstice EM is started. When the nickname service is added automatically to the MIS, the default MIS host and port number are assumed. If you want to specify a different MIS host or port number, add the nickname service to the MIS manually.
Note The MIS must be started before you add the nickname service to the MIS manually.
To add the nickname service to the MIS manually, type:
hostname% em_nnadd -m MPAhost [-h MIShost] [-n port] [-help]
- -m MPAhost specifies that the nickname server is running on the host named MPAhost.
- -h MIShost specifies that the MIS host is the remote host named MIShost. The -h flag is optional. The default host is the local host.
- -n port specifies that the nickname service uses port number port on the MIS host. The -n flag is optional. The default is port number 5555.
- -help prints the usage message for the em_nnadd command.
Assigning Nicknames to Managed Objects
Assigning nicknames to managed objects defines the mapping between FDNs of managed objects and nicknames you want to assign to the managed objects.
To define mappings between FDNs and nicknames, create a text file that contains the mappings. In the text file, define each mapping by using a pair of lines in the following format:
fdnnickname
- fdn is the FDN of the managed object. You must express the FDN in brace notation. For more information, see Section 2.2.6.3 Brace Notation for Relative and Fully Distinguished Names.
- nickname is the nickname associated with the FDN. nickname must be a text string without quotes.
Comment lines are allowed in the file. Start each comment line with the hash character (#).
Solstice EM does not impose any restrictions on the number of mappings in a file.
An example of mappings between FDNs and nicknames is shown in CODE EXAMPLE 5-8.
CODE EXAMPLE 5-8 Mappings Between FDNs and Nicknames
# This is a sample em_nnconfig input file. # Comment lines can be included. This line is a comment line. # Entries are organized in pairs of lines. # The first line in a pair is the FDN. # The next line that is neither blank nor a comment is the nickname.{ {{ systemId, "starless" }} } starless{ {{ systemId, "starless" }}, {{ satelliteId, "NorthernLights"}} } NL-sat{ {{ systemId, "starless" }}, {{ subsystemId, "EM-MIS"}}} MIS-subsystemIn this example, nicknames are assigned to managed objects as follows:
- The managed object identified by the FDN /systemId="starless" is assigned the nickname starless.
- The managed object identified by the FDN /systemId="starless"/satelliteId="NorthernLights" is assigned the nickname NL-sat.
- The managed object identified by the FDN /systemId="starless"/subsystemId/="EM-MIS" is given the nickname MIS-subsystem.
Loading Nickname Assignments Into the Nickname Service
Loading nickname assignments into the nickname service provides the nickname service with the information it requires to translate between FDNs and nicknames.
To load nickname assignments into the nickname service, type:
hostname% em_nnconfig fileWhere file is the name of a file that contains the nickname assignments that you want to load into the nickname service. The required format of this file is defined in Assigning Nicknames to Managed Objects.
5.3.2.2 Getting the Image Instance Associated With a Nickname
To get the Image instance associated with a nickname, call the static function find_by_nickname of the Image class. In the call to find_by_nickname, specify the nickname of the managed object you want to select. The find_by_nickname function returns the Image instance that represents the managed object you want to select. When you have obtained the Image instance, you can perform management operations by calling functions on this Image instance.
Code for getting the Image instance associated with a nickname is shown in CODE EXAMPLE 5-9.
CODE EXAMPLE 5-9 Getting the Image Instance Associated With a Nickname
... #include <pmi/hi.hh> // High Level PMI ... CDU nicnam = "NL-sat" ; Image sat_image = Image::find_by_nickname( nicnam ) ;if ( !sat_image ) { cout << "object not found" << endl; return 1 ; }int num_packets = sat_image.get_long("packetsReceived"); ...In this example, the Image that represents the managed object with the nickname NL-sat is returned by the call to find_by_nickname. The get_long function is called on this instance to get the value of the packetsReceived attribute of the managed object. For information on how to get the value of an attribute, refer to Section 5.6 Getting Attribute Values From an Object.
5.3.2.3 Getting and Setting Nicknames
Before you get or set the nickname of an Image instance, ensure that the Image instance is activated as explained in Section 5.2.2 Activating the Instance of Image.
To get the nickname of an Image instance, call the get_nickname function on the Image instance.
To set the nickname of an Image instance, call the set_nickname function on the Image instance.
5.4 Updating an Image Instance
Updating an Image instance loads attribute information from a managed object into the Image instance that represents the managed object. Each time you get or set attribute values of a managed object, or perform an action on a managed object, update the Image instance that represents it. Update the Image instance after you have initialized it.
To update an Image instance, call the boot function of the Image class. In the call to the boot function, specify a list of the attributes you want to get or set the values of.
Note You must pass the list of attributes to the boot function in an array, even if you want to update only one attribute in the Image instance.
Code for loading attribute information into an Image instance is shown in CODE EXAMPLE 5-10.
CODE EXAMPLE 5-10 Updating an Image Instance
... #include <pmi/hi.hh> // High Level PMI ... Array(DU) attrs; attrs = Array(DU)(1);attrs[0] = strdup("program");if (!channel_image.boot(attrs)) { cout << channel_image.get_error_string() << endl; return FALSE; } Array(DU) dish_attrs; dish_attrs = Array(DU)(1);dish_attrs[0] = strdup("vchipId");if (!dish_image.boot(dish_attrs)) { cout << dish_image.get_error_string() << endl; return FALSE; } ...In this example, arrays are defined as follows:
- An array named attrs contains the program attribute.
- An array named dish_attrs contains the vchipId attribute.
5.5 Deleting a Managed Object
To enable users of your applications to remove a managed resource from the network management environment, an application must delete the managed object that represents the managed resource.
An application can delete a managed object only if the specification of the managed object allows it to be deleted by a management operation. Specifically, the NAME BINDING clause of the GDMO specification of the managed object must contain the DELETE construct. Otherwise, any request to delete the managed object will be denied.
When an application attempts to delete a managed object that contains other managed objects, the result depends on how the DELETE construct is specified:
- If the DELETES-CONTAINED-OBJECTS modifier is applied to the DELETE construct, the managed object and all the managed objects it contains are deleted.
- Otherwise, the request to delete the managed object is denied. In that case, all the managed objects contained must be deleted before trying to delete the containing object.
Deleting a managed object involves:
- Selecting the managed object as described in Section 5.3 Selecting a Managed Object
- Removing the managed object from the MIS
5.5.1 Removing the Managed Object From the MIS
After you have specified the managed object you want to delete, remove it from the MIS by calling the destroy function of the Image class.
A call to the destroy function is shown in CODE EXAMPLE 5-11.
CODE EXAMPLE 5-11 Removing a Managed Object from the MIS
... #include <pmi/hi.hh> // High Level PMI ... if (!del_image.destroy()) cout << "Deletion failed" << endl; else cout << "Deletion succeeded" << endl; ...In this example, the overloaded NOT (!) operator acts on the call to destroy to verify that the managed object was removed from the MIS. If it was not removed, an error message explaining the reason for the failure is displayed.
5.5.2 Example Object Deletion Function
An example of a function that contains all the code for deleting a managed object is shown in CODE EXAMPLE 5-12.
CODE EXAMPLE 5-12 Example Object Deletion Function
... #include <pmi/hi.hh> // High Level PMI #include <rw/cstring.h> // Rogue Wave RWCString ... Boolean delete_object(RWCString fdn){ Image del_image(fdn.data());if (del_image.get_error_type() != PMI_SUCCESS) { cout << del_image.get_error_string() << endl; return FALSE; } // No need to waste time activating the Image object. If the // program reaches here, the Image object exists, so it can be // removed. if (!del_image.destroy()) cout << "Deletion failed" << endl; else cout << "Deletion succeeded" << endl; } ...5.6 Getting Attribute Values From an Object
An application monitors managed resources by getting attribute values from managed objects that represent those managed resources.
An application can get an attribute only if the specification of the attribute allows it to be read by a management operation. Specifically, the property list in the ATTRIBUTES construct of the attribute's GDMO specification must include the GET operation.
Getting attribute values from a managed object involves:
- Selecting the managed object as described in Section 5.3 Selecting a Managed Object
- Loading attribute information into the Image instance as described in Section 5.4 Updating an Image Instance
- Getting attribute values from the Image instance
To get an attribute value from the Image instance, call one of the functions of the Image class listed in TABLE 5-1 . The function to call depends on the data type of the attribute as defined in its ASN.1 module specification.
TABLE 5-1 Functions for Getting Attribute Values From an Image Instance String get_str Integer get_long Real get_dbl Arbitrarily long integer get_gint Any complex ASN.1 type get_raw
The get_raw function returns an instance of the Morf class. To process the Morf instance returned, call functions of the Morf class. For information on how to use the Morf class, refer to Chapter 9.
Each of the functions listed in TABLE 5-1 takes the name of attribute you want to get as a parameter. The attribute name must be specified exactly as it appears in the GDMO specification of the managed object. Attribute names are case sensitive.
If an attribute with the same name is defined in more than one of the GDMO documents loaded into the MIS, you must specify in which document the attribute you are interested in is defined.
To specify the document, prefix the attribute name with the document name specified in the MODULE construct of the managed object's GDMO specification, for example: "My Document":reusedAttribute.
Code for getting attribute values is shown in CODE EXAMPLE 5-13.
CODE EXAMPLE 5-13 Getting Attribute Values
... #include <pmi/hi.hh> // High Level PMI #include <rw/cstring.h> // Rogue Wave RWCString ...int id_number = dish_image.get_long("vchipId");Morf prog_info = channel_image.get_raw("program");if (!prog_info.has_value()) { return TRUE; } RWCString rating; // The program attribute is a choice between// NULL or { program_name, rating } // is_choice() will always be true if the Morf object is // constructed properlyif (prog_info.is_choice()) { // Now extract the contents of the program Morf newm = prog_info.extract(DU()); // If the program strings are in the attribute, // there will be a list of two elementsif (newm.is_list()) { // Now get the required element Array(Morf) mm = newm.split_array(); rating = mm[1].get_str().chp(); } else return TRUE; } else return TRUE; ...In this example functions are called to get attributes as follows:
- The get_long function is called to get the integer attribute vchipId.
- The get_raw function is called to get the complex attribute program.
Functions of the Morf class are called to process the Morf object returned by the get_raw function. For information on how to use the Morf class, refer to Chapter 9.
5.7 Setting Attribute Values of an Object
To control managed resources, an application sets attribute values for managed objects that represent those managed resources.
An application can set an attribute only if the specification of the attribute allows it to be set by a management operation. Specifically, the property list in the ATTRIBUTES construct of the attribute's GDMO specification must include the operation you want to perform when setting the attribute. Otherwise, any request to set the attribute will be denied. For more information on attribute-setting operations, refer to Section 5.7.1.3 Operation.
Setting attribute values of an object involves:
- Selecting the managed object as described in Section 5.3 Selecting a Managed Object
- Loading attribute information into the Image instance as described in Section 5.4 Updating an Image Instance
- Setting attribute values in the Image instance
- Updating the MIS with the changed values
5.7.1 Setting Attribute Values in the Image Instance
After you have selected the managed object and loaded attribute information from the managed object into the Image instance, call functions of the Image class to set attributes in the Image instance. The function to call depends on the data type of the attribute as defined in its ASN.1 module specification. The functions for setting attribute values in an Image instance are listed in TABLE 5-2 .
TABLE 5-2 Functions for Setting Attribute Values in an Image Instance String set_str Integer set_long Real set_dbl Arbitrarily long integer set_gint Any complex ASN.1 type set_raw
In the call to a function for setting an attribute value, you have to specify:
- The name of the attribute you want to set
- The value you want to set the attribute to
- The operation that you want to be carried out to set the attribute
Note Calling a function for setting an attribute value changes only the value cached in your application. To change the value in the actual managed object, you must propagate the change to the managed object as explained in Section 5.7.2 Updating the MIS With the Changed Values.
5.7.1.1 Attribute Name
The attribute name must be specified exactly as it appears in the GDMO specification of the managed object. Attribute names are case sensitive.
If an attribute with the same name is defined in more than one of the GDMO documents loaded into the MIS, you must specify in which document the attribute you are interested in is defined. To specify the document, prefix the attribute name with the document name specified in the MODULE construct of the managed object's GDMO specification, for example: "My Document":reusedAttribute.
5.7.1.2 Attribute Value
The value you specify must be consistent with any restrictions specified in the property list in the ATTRIBUTES construct of the attribute's GDMO specification.
5.7.1.3 Operation
The operation specifies how the attribute value is to be modified. The operation you want to perform must be in the property list in the ATTRIBUTES construct of the attribute's GDMO specification. It must be one of the operations listed in TABLE 5-3 .
TABLE 5-3 Operations for Setting Attributes REPLACE Replaces the existing value with that specified in the function call. It corresponds to the REPLACE operation in a property list. REPLACE is the default operation. INCLUDE Adds the value specified in the function call to the current value of a multi-valued attribute. It corresponds to the ADD operation in a property list. Specify the INCLUDE operation for multi-valued attributes only. If you specify the INCLUDE operation for a single-valued attribute, an exception is thrown. EXCLUDE Removes the value specified in the function call from the current value of a multi-valued attribute. It corresponds to the REMOVE operation in a property list. Specify the EXCLUDE operation for multi-valued attributes only. If you specify the EXCLUDE operation for a single-valued attribute, an exception is thrown. IGNORE Specifies that the value specified in the function call is the initial value of the attribute. If the attribute has already been initialized, its value is not changed. DEFAULT Replaces the existing value with the default value defined in the property list in the ATTRIBUTES construct of the attribute's GDMO specification.
5.7.2 Updating the MIS With the Changed Values
After you have set attributes in the Image instance, update the MIS with the changed values to propagate the changes to the managed object itself. To update the MIS with the changed values, call the store function of the Image class.
5.7.3 Checking If the MIS Has Been Updated
Updating the MIS more frequently than necessary can impair the performance of your application. To enhance the performance of your application, check if the MIS has been updated before you update it with changed values.
To check if the MIS has been updated, get the value last set by your application and compare it to the value stored in the MIS. For information on how to get the value stored in the MIS, refer to Section 5.6 Getting Attribute Values From an Object.
To get the value last set by your application, call one of the functions of the Image class listed in TABLE 5-4 . The function to call depends on the data type of the attribute as defined in its ASN.1 module specification.
TABLE 5-4 Functions for Getting the Value Last Set by an Application String get_set_str Integer get_set_long Real get_set_dbl Arbitrarily long integer get_set_gint Any complex ASN.1 type get_set_raw
The get_set_raw function returns an instance of the Morf class. To process the Morf instance returned, call functions of the Morf class. For information on how to use the Morf class, refer to Chapter 9.
Each of the functions listed in TABLE 5-4 takes the name of attribute you want to get as a parameter. The restrictions on these attribute names are identical to those given in Section 5.7.1.1 Attribute Name.
5.7.4 Real and Imaginary Values in an Image Instance
To enable you to compare the value last set by your application with the value stored in the MIS, an Image instance stores the following values for each attribute of a managed object:
- A real value. The real value represents the value in the MIS.
- An imaginary value. The imaginary value represents the value set by a call to one of the functions for setting attribute values listed in TABLE 5-2 .
When the MIS is updated, the real value is set to the imaginary value. When an Image instance is activated, the real value is updated, but the imaginary value is left unchanged.
When you get an attribute value as described in Section 5.6 Getting Attribute Values From an Object, you retrieve the real value from the Image instance. When you get the value last set by your application as described in Section 5.7.3 Checking If the MIS Has Been Updated, you retrieve the imaginary value from the Image instance.
5.7.5 Example
Code for setting an attribute value is shown in CODE EXAMPLE 5-14.
CODE EXAMPLE 5-14 Setting an Attribute Value
... #include <pmi/hi.hh> // High Level PMI ... // Prevent any further alarms generated in the system // from being logged.Image test_image("systemId="myhost""logId=string:\"AlarmLog\""); test_image.boot();test_image.set_str("administrativeState", "locked"); test_image.store(); ...In this example the administrativeState attribute of the AlarmLog object is set to the text locked.
5.8 Performing an Action on an Object
An action is an operation that cannot be modelled by a pre-defined operation such as getting or setting an attribute. An action enables you to implement specialized behavior, for example, changing attributes of one or many objects in a single operation or providing the results of a query in a particular format.
Performing an action on an object involves:
- Selecting the managed object as described in Section 5.3 Selecting a Managed Object
- Loading attribute information into the Image instance as described in Section 5.4 Updating an Image Instance
- Sending the action request
To send an action request, call one of the functions of the Image class listed in TABLE 5-5 , depending on the format of the action parameter.
TABLE 5-5 Functions for Sending an Action Request to a Managed Object Text call The call function returns the action reply in text form. Encoded call_raw You have to construct an instance of the Morf class to represent the action parameter. The call_raw function returns the action reply in encoded form as an instance of the Morf class.
In the call to call or call_raw you have to specify:
- The name of the action you want to perform. The action name must be specified exactly as it appears in the GDMO specification of the managed object. Action names are case sensitive.
- The action parameter. The syntax of the action parameter must be specified exactly as it appears in the GDMO specification of the managed object.
Code for sending an action request is shown in CODE EXAMPLE 5-15.
CODE EXAMPLE 5-15 Sending an Action Request
... #include <pmi/hi.hh> // High Level PMI ... char * topo_name2Id(char * host, char * nodename){ char dn[1024] = ""; char action_name[100] = "topoNodeGetByName"; char action_para[100]; sprintf(action_para,"'%s'", nodename); sprintf(dn,"/systemId='%s'/topoNodeDBId=NULL", host); Image topo = Image(dn); ... Syntax syn_input = topo.get_param_syntax(action_name); ... Morf morf_input(syn_input, DU(action_para)); ... Morf morf_result = topo.call_raw(DU(action_name), morf_input);if (morf_result.get_error_type() != PMI_SUCCESS) { cout << morf_result.get_error_string() << endl; exit(2); } ... }In this example, the call_raw function of the Image class is called in the body of a function named topo_name2Id. The name of the action to be performed is topoNodeGetByName.
The action parameter is a Morf object constructed as follows:
- The get_param_syntax function is called to obtain the syntax of the topoNodeGetByName action parameter.
- The following are passed to the constructor of the Morf class:
If the call to call_raw is unsuccessful, the reason for the failure is printed.
For information on how to use the Morf class, see Chapter 9.
The GDMO specification of the topoNodeGetByName action is shown in CODE EXAMPLE 5-16.
CODE EXAMPLE 5-16 GDMO Specification of the topoNodeGetByName Action
... topoNodeGetByName ACTION BEHAVIOUR topoNodeGetByNameBehaviour BEHAVIOUR DEFINED AS !This action returns the topoNodeId of the topoNode whose topoNodeName attribute matches the input name!; ; WITH INFORMATION SYNTAX EM-TOPO-ASN1.TopoNodeName; WITH REPLY SYNTAX EM-TOPO-ASN1.TopoNodes;REGISTERED AS { em-topo-action 1 }; ...The ASN.1 definitions of the data types used by the topoNodeGetByName action are shown in CODE EXAMPLE 5-17.
CODE EXAMPLE 5-17 ASN.1 Definitions of Data Types Used by topoNodeGetByName
... TopoNodeName ::= GraphicString(SIZE(0..255)) TopoNodeId ::= INTEGER (0..4294967295) TopoNodes ::= SET OF TopoNodeId ...5.9 Tracking Changes to an Object
Tracking changes to an object updates an Image instance with changes to the managed object that the instance represents. Tracking changes ensures that your network management application has access to current data about your managed resources.
Depending on your requirements, you can track changes to an object automatically or manually. Automatically tracking changes requires you to write less code but gives you less control than manually tracking changes.
5.9.1 Automatically Tracking Changes to an Object
Automatically tracking changes to an object causes the MIS to update the Image instance whenever the MIS receives an attribute value change notification for that instance.
Track changes to an object automatically if you want to simplify the application development process (for example during the prototype phase) or if you do not require control over when an Image instance is updated.
To track changes to an object automatically, set the TRACKMODE property of the Image instance to TRACK. To set the TRACKMODE property of an Image instance, call the set_prop function of the Image class before activating the instance.
Code for setting the TRACKMODE property to TRACK is shown in CODE EXAMPLE 5-18.
CODE EXAMPLE 5-18 Setting the TACKMODE Property of an Image Instance
... #include <pmi/hi.hh> // High Level PMI ... im.set_prop(duTRACKMODE, duTRACK); ...5.9.2 Manually Tracking Changes to an Object
Track changes to an object manually if you need to control when an Image instance is updated. For example, if you need all attributes in an Image instance to have particular values before you perform an operation, manually track changes to the object that the Image instance represents.
Tracking changes to an object manually involves:
- Setting the TRACKMODE property of the Image instance to SNAP
- Using callback functions to update an Image instance with changes to the managed object that the instance represents
If you track changes to an object manually, you have to write code in your callbacks for updating the Image instance. Having to write your own code makes coding your application more complicated. But it gives you control over which changes you update the Image instance with, and enhances the performance of your application.
For information on how to use callback functions to update an Image instance, refer to Section 7.2 Processing Information in Event Notifications.
5.10 Retrieving Data From the Metadata Repository
The metadata repository (MDR) stores information about managed objects that is defined in your object model. Retrieve data from the metadata repository when:
- You want to verify what is already loaded into the MDR before loading an updated object model.
- You want your application to process attributes differently depending on their data types. For example, you want how an attribute is displayed to depend on its ASN.1 type.
The MDR is represented as a managed object in the Solstice EM MIS. To retrieve metadata from the MDR, an application must be able to perform an action on the MDR managed object.
Performing an action on the MDR managed object involves:
- Selecting the MDR managed object
- Updating the Image instance that represents the MDR managed object
- Sending the action request
5.10.1 Selecting the MDR Managed Object
When you perform an action on the MDR managed object, you have to select it by specifying its FDN. To select a managed object by specifying its FDN, create and initialize an instance of the Image class, specifying only the FDN. For more information, refer to Section 5.3.1 Selecting a Managed Object by Specifying its FDN or LDN.
The MDR managed object is contained by the system object and is named by the metaName attribute, which always has the value MDR. Therefore, the FDN of the MDR managed object is as follows:
/systemId="host"/metaName="MDR"Where host is the host name of the MIS associated with the MDR.
Code for selecting the MDR managed object is shown in CODE EXAMPLE 5-19.
CODE EXAMPLE 5-19 Selecting the MDR Managed Object
... #include <hi.hh> // High Level PMI ... sprintf(dn,"/systemId=\"%s\"/metaName=\"MDR\"", server); Image mdr = Image(dn); ...5.10.2 Updating the Image Instance That Represents the MDR Managed Object
After you have selected the MDR managed object, update the Image instance that represents it. To update an Image instance, call the boot function of the Image class. For more information, refer to Section 5.4 Updating an Image Instance.
Code for updating an Image instance that represents the MDR managed object is shown in CODE EXAMPLE 5-20.
CODE EXAMPLE 5-20 Updating the Image Instance that Represents the MDR
... #include <hi.hh> // High Level PMI ... // Activate the mdr object.if (!mdr.boot()) { cout << mdr.get_error_string() << endl; exit(2); } ...5.10.3 Sending the Action Request
To send an action request to retrieve metadata from the MDR, call the call function of the Image class. For more information, refer to Section 5.8 Performing an Action on an Object. In the call to the call function, specify:
- The name of the action you want to perform. The action to use depends on the metadata you want to retrieve.
- The action parameter. The action parameter depends on the action you want to send.
The actions for retrieving metadata from the MDR are shown in TABLE 5-6 .
TABLE 5-6 Actions for Retrieving Metadata From the MDR The name of the ASN.1 module that an attribute is defined in getAttribute The name of each GDMO document loaded into the MDR getAllDocuments Complete information in text format about an ASN.1 module getAsn1Module Complete information in text format about a class getObjectClass A list of all items defined in a GDMO document and their OIDs getDocument The name of an item identified by an OID getOidName A list of all packages that characterize a managed object class getPackagesByOC Information on the attributes, actions, and notifications defined in a package getPackage Information on the notifications and attributes, when OID for a particular notification is given. getNotificationAndAttributeIds
Code for sending an action request is shown in CODE EXAMPLE 5-21.
CODE EXAMPLE 5-21 Sending an Action Request
... #include <hi.hh> // High Level PMI #include <rw/cstring.h> // Rogue Wave RWCString ... // Send the action and get the result data. DU mdr_data = mdr.call(action_name, action_para); ...In this example, the call function of the Image class is called to send an action request. The variable action_name specifies the name of the action to be performed. The variable action_para specifies the action parameter. The initialization of the action_name and action_para variables is not shown in the example.
5.11 Simulating an Agent Object
If the agent and manager applications are being developed simultaneously, you need to test your manager application separately from the agents it will manage. If you want to test your management application separately, you can use the MIS to simulate an agent.
Using the MIS to simulate an agent involves:
- Containing managed objects in the MIS
- Making read-only attributes modifiable
- Loading GDMO descriptions into the MIS
- Creating and modifying objects in the MIS
5.11.1 Containing Managed Objects in the Solstice EM MIS
In a live network management system, managed objects are contained in an agent. When the MIS is acting as an agent in a simulation, managed objects must be contained in the MIS itself. To enable managed objects to be contained in the MIS, managed object classes that would in a live system be instantiated directly under the agent object must be instantiated under the system object.
To allow a managed object class to be instantiated under the system object, define a name binding clause in which the superior object class is system. An example of such a name binding clause is given in CODE EXAMPLE 5-22.
CODE EXAMPLE 5-22 Name Binding Clause for Instantiation Under system
... satellite-system NAME BINDING SUBORDINATE OBJECT CLASS satellite; NAMED BY SUPERIOR OBJECT CLASS "Rec. X.721 | ISO/IEC 10165-2 : 1992":system; WITH ATTRIBUTE satelliteId; BEHAVIOUR satellite-systemBehaviour BEHAVIOUR DEFINED AS ! For the test agent, create local instances of satellite under the system branch of the tree !; ; CREATE; DELETE ONLY-IF-NO-CONTAINED-OBJECTS;REGISTERED AS { satman-binding 1 }; ...In this example, the satellite managed object class can be instantiated under the system object.
5.11.2 Making Read-Only Attributes Modifiable
The GDMO specification of some attributes does not permit them to be modified by a management operation. For example, an attribute that represents the status of a device on the network is normally defined as a read-only attribute. However, if you want to use Solstice EM tools to modify such attributes when you are simulating an agent, you will need to make such attributes modifiable. To make a read-only attribute modifiable, add one of the following operations to the property list in the ATTRIBUTES construct of the attribute's GDMO specification:
- Replace
- Add
- Remove
5.11.3 Loading GDMO Descriptions Into the MIS
Load the GDMO descriptions of your managed object classes into the MIS to make them available to Solstice EM. For information on how to load the GDMO descriptions into the MIS, refer to Section 2.6 Making Your Object Model Available to Solstice EM.
5.11.4 Creating and Modifying Objects in the MIS
In a live network, managed objects are created and modified as a result of activity on the network. When you use the MIS to simulate an agent, use Solstice EM tools to simulate such activity by creating and modifying objects in the MIS. You can create and modify objects in the MIS interactively, or from the command line.
5.11.4.1 Creating and Modifying Objects Interactively
Creating and modifying objects interactively provides immediate verification of the attribute values you specify, thereby making it simple to set the values of complex ASN.1 types. To create and modify objects in the MIS interactively, use the MIS Objects tool.
5.11.4.2 Creating and Modifying Objects From the Command Line
Creating and modifying objects from the command line saves time and effort when you need to create and modify large numbers of objects, or when you need to repeat the same operations several times during testing.
To create and modify objects from the command line, use the em_objop utility. The em_objop utility creates and modifies objects in accordance with information supplied in an em_objop script, which is a text file.
Starting the em_objop Utility
To start the em_objop utility, type the following command:
prompt% em_objop -f filewhere file is an em_objop script specifying how objects are to be created or modified.
Format of an em_objop Script
An em_objop script contains one or more commands. Each command specifies an operation to be carried out on an object. The format of a command is as follows:
operation{OPTION = 'encoding'OC = mocOI = moiattr1 = val1...attrN = valN}The variable parts of this format are explained in TABLE 5-7 .
TABLE 5-7 Variable Parts of the Format of an em_objop Script operation The operation you want to be performed. It must be one of the following keywords: CREATE - Create and initialize an object SET - Set one or more attribute values of an object DELETE - Delete an object DERIVE - Derive an instance of the Album class encoding td> The encoding of the em_objop script. It must be one of the following keywords: HEX - Hexadecimal encoding OCTAL - Octal encoding moc The managed object class of the object that the operation is to be performed on. moi The fully distinguished name of the object that the operation is to be performed on. If operation is DERIVE, moi is a derivation string. For more information, refer to Section 6.3.2 Format of a Derivation String. attr1 The name of the first attribute you want to set. Omit if operation is DELETE. val1 The value that you want to set attr1 to. attrN The name of the Nth attribute you want to set. Omit if operation is DELETE. valN The value that you want to set attrN to.
Example em_objop Scripts
Example em_objop scripts are given as follows:
- Creating an object - CODE EXAMPLE 5-23
- Setting an attribute value - CODE EXAMPLE 5-24
- Deleting an object - CODE EXAMPLE 5-25
- Deriving an Album instance - CODE EXAMPLE 5-26
CODE EXAMPLE 5-23 em_objop Script for Creating an Object
CREATE{ OC=satellite OI='satelliteId="NorthernLights"' administrativeState=locked operationalState=enabledselfDestructCode='{{{"T", 4, {{0 1}}}},{{"R",8,{{1 3}}}},{{"E",9,{{1 5}}}}}' }
CODE EXAMPLE 5-24 em_objop Script for Setting an Attribute Value
SET{ OC = 'autoManagementEntry' OI = 'subsystemId="EM-MIS"/autoManagerId="TheAutoManager"/autoEntr yId = "MIBII_IsSnmpSystemUp_Host"' autoEntryTopoType = 'Ultra2' }
CODE EXAMPLE 5-25 em_objop Script for Deleting an Object
DELETE{ OC = 'autoManagementEntry' OI = 'subsystemId="EM-MIS"/autoManagerId="TheAutoManager"/autoEntr yId = "MIBII_IsSnmpSystemUp_Host"' }
CODE EXAMPLE 5-26 em_objop Script for Deriving an Album Instance
DERIVE{ OC = 'autoManagementEntry' OI = 'subsystemId="EM-MIS"/autoManagerId="TheAutoManager"/LV(1)' }5.12 Representing MIS Instances Locally in an Application
Using an instance of Image to store all the data in a managed object simplifies the coding of your applications, but it does require a lot of memory. If memory is scarce, you can save memory by defining your own C++ class to represent managed objects locally in an application.
Defining your own classes is particularly helpful when you have a managed object class that has many attributes and your application is controlling and monitoring only a small subset of them. In such a situation, you can create a class that has only the attributes that are relevant to your application.
Defining your own class makes coding your application more complicated. You have to write your own code for tracking changes, deletions, and creations. However, if your application is managing a large number of objects, you may need to define your own class to save memory.
If you are unsure if you need to define your own class, write a prototype application that uses the Image class, and test the performance of the prototype. Coding an application in this way is simple and rapidly provides useful performance data.
For example, the satellite, channel, and dish managed object classes in the satellite example have several attributes. But many of the example applications need only the identity, FDN, and position of a satellite, channel, or dish object. To save memory, the Node class is defined to hold important data common to the satellite, channel, and dish managed object classes.
For the dish managed object class, many of the example applications monitor only the vchipId attribute. To save memory, the Dish class is defined to hold this attribute.
CODE EXAMPLE 5-27 shows the definition of the Node and Dish C++ classes.
CODE EXAMPLE 5-27 C++ Representation of Managed Object Classes
class Node { public: Node(); Node(RWCString namestr, RWCString fdnstr); ~Node();int operator == (const Node &other) const { if (name == other.name) return(1); else return(0); } RWCString get_name(); RWCString get_fdn(); void get_location(Geo &lat, Geo &longit); void set_location(Geo lat, Geo longit); RWCString name; RWCString fdn; Coordinates location; };class Dish : public Node { public: Dish(); ~Dish(); Dish(Node newnode); int vchip; };
|
Sun Microsystems, Inc. Copyright information. All rights reserved. |
Doc Set | Contents | Previous | Next | Index |