Solstice Enterprise Manager 4.1 Developing C++ Applications Doc Set ContentsPreviousNextIndex


Chapter 5

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.

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:

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:

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:

Code for creating and initializing an instance of the Image class is shown in CODE EXAMPLE 5-1.

CODE EXAMPLE 5-1   Creating and Initializing an Image Instance 
...
#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;
    }
...
}
...

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:

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:

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:

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:

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:

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:

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

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]

Where:

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:

fdn
nickname

Where:

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-subsystem

In this example, nicknames are assigned to managed objects as follows:

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 
file

Where 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:

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:

Deleting a managed object involves:

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:

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 
Data Type Function
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 properly
if (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 elements
    if (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:

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 
Data Type Function
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 
Operation Result
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 
Data Type Function
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:

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 
Format Function Comment
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:

    • The Syntax object returned by get_param_syntax
    • The node name passed to the topo_name2Id function

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 
Metadata Action
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 
file 

where 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 = moc
OI = moi
attr1 = 
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
    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:

    CODE EXAMPLE 5-23   em_objop Script for Creating an Object 
    CREATE
    
    {
    
    OC=satellite
    
    OI='satelliteId="NorthernLights"'
    
    administrativeState=locked
    
    operationalState=enabled
    
    selfDestructCode='{{{"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