Solstice Enterprise Manager 4.1 Customizing Guide | ![]() ![]() ![]() ![]() ![]() |
Request Condition Language
Request Condition Language (RCL) is a script language used to build conditions. Using RCL you can build up a library of conditions that can be deployed as building blocks in the construction of request templates in the Design Advanced Requests.
This chapter describes the following topics:
- Section 20.1 Conditions
- Section 20.2 Types of Operands
- Section 20.3 Constants
- Section 20.4 Variables in a Condition
- Section 20.5 Data Types
- Section 20.6 System Variables
- Section 20.7 Attributes
- Section 20.8 Operators
- Section 20.9 Control Structures
- Section 20.10 Timestamp Arithmetic
- Section 20.11 Error Checking
20.1 Conditions
A condition is a sequence of one or more statements written in the Solstice Enterprise Manager (Solstice EM) RCL. With the exception of compound expressions built using IF, IF ELSE, FOR EACH, and WHILE constructs, each RCL statement must end with a semicolon.
There are two possible roles that a condition can play in a template:
- A single condition is used to define when a transition from one state to another in a template will occur.
- Conditions can also function as actions that are executed as the result of a transition. Multiple conditions can be specified as actions for the same transition and they will be executed in the order listed in the transition.
When a condition is used to define when a transition will occur, the sequence of statements must evaluate as true or false. That is, the last statement must return a result that can be treated as false (null) or true (not null). If the condition returns a value of true, this causes the transition to occur.
However, when a condition is used to define an action that occurs as the result of a transition, the condition's return value is ignored.
This chapter covers the operands, variables, attributes, and other components that make up RCL. RCL also provides a library of built-in functions that can be used in building templates. The built-in functions are described, in alphabetical order, in Chapter 22.
20.2 Types of Operands
The operators or built-in named operators that are currently implemented support primitive data types.
The RCL has three basic types of operands:
- Constants
- Variables
- Attributes
Each operand has a type and a value. The type is represented internally as an Asn1Type. For example, an integer operand has the type INTEGER. The value of an operand is represented internally as an Asn1Value. A built-in operator assigns types and values to variables dynamically. Type declarations are not required for variables. For example, the variable $counter is initially defined as an integer type when the following assignment is encountered in a condition:
$counter = 0;20.3 Constants
The following table shows the list of constants represented in the RCL syntax.
20.4 Variables in a Condition
Variables can be used to store temporary information. For example
:
$last_sys_up_time = sysUpTime;In this RCL statement, $last_sys_up_time is a user variable to store the value obtained from the SNMP sysUpTime attribute.
Variables have the scope of the request template. Every request that uses a template thereby has all the variables named in the template. Each request has its own storage area, the StackFrame. All variables are assigned to storage locations in the StackFrame. Thus, when a variable is defined once in the request template, instances of it are created in each request's StackFrame. Values are retained throughout the life of the request.
A condition expression can make use of two classes of variables:
- System Variables--These are always present in each request. Their values are set by the Solstice EM MIS. System variables are listed in TABLE 20-2. For examples illustrating the use of RCL system variables, see Chapter 21.
- User-defined Variables--These comprise all user-deployed variables other than system variables. They cannot duplicate the name of a system variable. They are not declared. Whenever a variable is assigned, it is automatically assigned a type corresponding to the result of the expression assigned to it. If a variable has never been assigned, it is said to be undefined. There is a function, defined(), (described in Section 22.2.9 Defined") to test whether a variable has been defined.
20.4.1 Variable Names
The name of a variable begins with $ (dollar sign) followed by one or more alphanumeric characters or _ (underbar).
Note Case is significant in variable names.
20.4.2 Scope of Variables
Each request that implements a request template has a complete set of the variables defined in all of the conditions used anywhere in that template. The values of those variables are local to the request. That is, in each request, variables have values that are independent of their values in any other request. The values of variables within a request persist as long as the request lives.
The scope of a variable name is the template in which it occurs. That is, a variable that is set by one condition within a template can be used by any other condition in the same template. However, variables are defined when a condition in which it occurs is evaluated. A variable defined in a condition that has not yet been evaluated in a request, is not available for conditions that occur earlier in that request template.
20.5 Data Types
Because the Design Advanced Requests functions in a CMIP and an SNMP framework, Asn1Values and Asn1Types are used throughout the RCL. Any variable, attribute, or constant carries the Asn1Type along with it. For example, in the expression:
$int_val = 10;$int_val is a variable and is assigned the value 10. It is automatically assigned the Asn1Type INTEGER. Also, attributes have type information associated with them.
Because typing is dynamic, a variable's type is defined as the currently assigned type. Thus $int_val can be changed to type REAL as follows:
$int_val = 10.0;Variables can be assigned arbitrary Asn1Values of arbitrary Asn1Type. Thus it is possible to add new operators to the language that deal with any type other than those listed in TABLE 20-1 with which most operators deal. An example of such an operator is TrapSpecificType, which takes as input an operand of type InternetActionInfo.
20.6 System Variables
The names and types of the available system variables are shown in the following table.
TABLE 20-2 System Variables Available to a Condition $eventOC OID Object class of last/current event $eventOI ObjectInstance Object instance of event $eventInfo eventInfo eventInfo of eventType $eventTime GeneralizedTime Actual time the event was generated $eventType OID OID of the event type of the last event $messType INTEGER Type of current message (refer to TABLE 21-3 for $messType values) $multipleInstance BOOLEAN For SNMP polls only. True if the polled object has multiple instances, False otherwise. $pollOC ObjectClass Object class last polled or being currently polled $pollfdn ObjectInstance Object instance being polled $pollFdnSet SET OF ObjectInsance Set of distinguished names pointing to the managed object instances configured for the target device. Assigned when request launched against a selected element in the Network Views. $pollTime GeneralizedTime Delay until the first poll is sent and the time between successive polls, in seconds $severity INTEGER Severity level of current state
Chapter 21 contains examples illustrating the use of system variables.
20.7 Attributes
In addition to constants, variables, operators, and built-in functions, an expression in the RCL can refer to an attribute of a managed object. An attribute has both a name (determined in the GDMO description of the object in which it occurs) and a value. When an attribute is used in a condition, it is assigned storage in the same way that storage is allocated for a variable. The scope of an attribute is the request template in which it occurs. Each request has its own copy of the attribute, independent of any other request.
Each attribute has a type. The type is determined by the object's description, as recorded in the MetaData Repository (MDR). When a condition refers to an attribute, the Nerve Center queries the MDR and assigns the attribute's type accordingly.
An attribute within a request reflects the current condition of some attribute of a managed object. To obtain current information, the Nerve Center schedules polls for all attributes that are referred to in the conditions that must be tested for the current state of each request. The Nerve Center also schedules polls for the attributes referred to in the actions for transitions leading from the current state. That is, for every request, the Nerve Center tracks its current state, and for that state, schedules a poll for every attribute that must be tested to determine whether there will be a transition from that state. When the response to a poll arrives, the attribute's value in the request is updated before the conditions are evaluated.
The value of an attribute within a request is set only by the mechanism just described; you cannot use the = operator to assign a value to an attribute. Therefore an attribute name cannot appear on the left side of an assignment.
Like a variable, an attribute is "declared" automatically when used in a condition. It becomes "defined" when a notification assigns a value to it.
20.7.1 Syntax of Attribute Names
The name of an attribute can be written in either of two forms:
- &<label_name>--<label_name> is the name as it occurs in the relevant GDMO description of a managed object class. & is to be used if an attribute or variable is passed as an argument in such functions as extract(), define(), and undefine(). The ampersand is used to pass the address of the variable or attribute in the Stack Frame.
- "<doc_name>":<label_name>--A label <label_name> may be preceded by the name of the GDMO document in which the label occurs. The document name is enclosed in double quotes. The document name and the label name are separated by a colon.
Note It is recommended that the second format be used for attribute names to avoid any potential name collisions that occur when the same label name is defined in multiple documents.
For example, the attribute sysContact specified in the document IIMCRFC1213-MIB, is written:
"IIMCRFC1213-MIB":sysContact20.8 Operators
The RCL uses the same operators as C (for example, = for assignment, == for a test of equality, * for multiply, and so on). In addition, there are built-in named operators whose syntax resembles the syntax of functions in the C programming language.
Operators are arithmetical, logical, and relational. Each operator or built-in named operator specifies the input argument and types that it can handle.
The following operator symbols are supported by the RCL.
See the following table.The assignment operator can be used to assign values or types to variables.
Note You cannot use = to assign or set values of attributes.
The arithmetic operators are defined for INTEGERS and REAL data types. Modulus is defined only for INTEGERS.
Note Because the hyphen within an attribute name could be confused with a minus sign, a minus sign must be surrounded by blanks.
For example:
10 - 5; This is correct10-5; This is a syntax error
- There are no implicit type conversions. That is, 5/2 yields an integer result, so if you expect the result to be 2.5, you need 5.0/2.0 (as in C).
- The relational and equality operators accept not only integer or real arguments, but can also be used to compare arbitrary Asn1Values (in the same way as the CMIS Filter constructs).
- Statements built up using the logical operators are completely evaluated. That is, each operand of a complex expression, built using the AND, OR, and NOT operators, is evaluated. Thus, "short circuiting" is not implemented, that is, evaluation of the component expressions does not stop even if the value of the complex expression is already known from the evaluation of initial components. Logical operators operate only on Boolean values, Integers, and Reals. The names of the logical operators are not case sensitive.
20.8.1 Logical Operators
The following example illustrates the use of an OR statement to define a condition for a transition. First, the user variables $ncType and $itType are defined as nerveCenterAlarm and internetAlarm (respectively) in the following condition, which also subscribes to receive SNMP traps. This condition might be used to initialize the template in the Ground state.
$ncindx=Subscribe("nerveCenterAlarm");$itindx=subscribeOi("internetAlarm","{}",$pollfdn);$ncType=NameToOid("nerveCenterAlarm");$itType=NameToOid("internetAlarm"); true;In the following example, the OR operator is used in a condition that forces a transition if the system variable $eventType indicates that either an internetAlarm or a nerveCenterAlarm has been received:
$eventType == $ncType OR $eventType == $itType;20.8.2 Bitwise Operators
The bitwise operators numeric AND, inclusive OR, and exclusive OR perform binary operations on numeric operands and generate numeric results. For example,
20|24compares the binary numbers
20 = 0001010024 = 00011000and generates a binary number with a 1 bit wherever either (or both) of the operands has a 1 bit. The resulting value is:
28 = 0001110020.8.3 Precedence and Associativity
The precedence and associativity of operators are summarized in the following table.
Parentheses force precedence in the usual way.
20.9 Control Structures
RCL supports four constructs that can be used to build control structures within a condition: IF, IF ELSE, WHILE, and FOREACH. These four constructs are used to control the conditions under which a block of RCL statements are to be executed. An RCL statement block consists of zero or more RCL statements, each terminated with a semicolon. Also, a statement block must be preceded by a left curly brace and followed by a right curly brace.
20.9.1 IF Constructs
Syntax:
IF (<boolean_expression>)
{<statement_block>}<boolean expression> must be an RCL expression that evaluates as either true or false. <statement_block> consists of zero or more RCL statements, each terminated with a semicolon. The block of statements must be surrounded by curly braces, as shown above. The RCL statements contained in <statement_block> are executed if <boolean_expression> evaluates to true. For example:
IF ($eventOi == $pingFdn){$ping_response_count = ping_response_count+1;}20.9.2 IF ELSE Constructs
Syntax:
IF (<boolean_expression>)
{<statement_block1>}
ELSE
{<statement_block2>}<boolean expression> must be an RCL expression that evaluates as either true or false. <statement_block1> and <statement_block2> each consists of zero or more RCL statements, each terminated with a semicolon. Each block of statements must be surrounded by curly braces, as shown above. The RCL statements contained in <statement_block1> are executed if and only if <boolean_expression> evaluates to true.
The block of statements comprised in <statement_block2>, the ELSE construct, are executed if and only if <boolean_expression> in the preceding IF statement evaluated to false. For example:
$FdnStr = AsnToStr($dn,TRUE);$result = AnyStr($FdnStr,"RPC");IF ($result == TRUE){print($FdnStr);$count = $num + 1;}ELSE{$count = $count+1;}20.9.3 WHILE Constructs
Syntax:
WHILE (<boolean_expression>)
{<statement_block>}<boolean_expression> must be an RCL expression that evaluates to either true or false. <statement_block> consists of zero or more RCL statements, each terminated with a semicolon. The statements comprised in <statement_block> are executed if <boolean_expression> evaluates to true. After the statements in <statement_block> have been executed, <boolean_expression> is evaluated once again. So long as <boolean_expression> remains true, the statements in <statement_block> continue to be executed in a repetitive cycle.
The following is an example of a condition that uses a WHILE loop to extract the RPC proxy table FDN from $pollFdnSet in order to set the $pollfdn to ping-reach, the reach attribute group of the RPC ping agent.
20.9.4 FOREACH Constructs
Syntax:
Foreach name in (<list_expression>)
{<statement_block>}<list_expression> must be of type SEQUENCE OF or SET OF. The block of statements comprised in <statement_block> is executed once for each element of the set or sequence, using name as a variable to represent the current element in each cycle. The variable name is automatically assigned the appropriate type for each element that it represents. If <list_expression> is not of type SEQUENCE OF or SET OF, <statement_block> is executed exactly once with name assigned the entire value of <list_expression>. The end of the block of statements in <statement_block> is marked by the final curly brace. For example:
foreach $var in (collectionInfoList){print($var);}The RCL FOREACH construct is similar to the UNIX Shell Foreach construct.
20.9.5 Nested Constructs
A statement block in an IF, IF ELSE, WHILE, or FOREACH construct can contain additional constructs. For example, an ELSE construct could contain another IF ELSE construct, such as the following:
IF (<boolean_expr1>) {<RCL_statement1>}ELSE{IF (<boolean_expr2>) {<RCL_statement2>} ELSE {<RCL_statement3>}}Similarly, a WHILE or FOREACH construct might contain an IF ELSE construct within its statement block.
The following is an example of an IF ELSE construct used to log nerveCenterAlarms in response to enterprise-specific traps:
20.10 Timestamp Arithmetic
Timestamps are of the type GeneralizedTime. The system variables $eventTime and $pollTime are of that type.
The following operators can accept Timestamp arguments or return Timestamp results:
- <Timestamp1> = <Timestamp2> + <integer>
- <Timestamp1> = <Timestamp2> + <real>
- <real> = <Timestamp1> - <Timestamp2> (result in milliseconds)
- <Timestamp1> = <Timestamp2> - <integer>
- <boolean> = <Timestamp1> > <Timestamp2>
- <boolean> = <Timestamp1> >= <Timestamp2>
- <boolean> = <Timestamp1> <= <Timestamp2>
- <boolean> = <Timestamp1> < <Timestamp2>
- <boolean> = <Timestamp1> == <Timestamp2>
- <boolean> = <Timestamp1> != <Timestamp2>
In the following example, a difference greater than six seconds between the current system time on the MIS machine and the time when an event was generated on a remote machine is used to define a condition for a transition.
$curtime = getTimeStamp();($eventTime - $curtime) > 600;In this case the transition would occur if the statement evaluates to True.
20.11 Error Checking
The Design Advanced Requests Tool checks and catches lexical and syntactic errors at the time you try to save the condition's definition. If it finds an error, the Design Advanced Requests displays an error dialog, and the offending condition is not saved. If there are any references to attributes in conditions, the Design Advanced Requests checks to determine if the attribute is known to the MIS. An attribute is not known to the MIS if it is not referred to in a GDMO document that has been loaded into the MIS. If an attribute is not known to the MIS, Design Advanced Requests displays an error dialog if you try to save the condition, and the condition is not saved.
If the condition survives the lexical and syntactic check, the Design Advanced Requests engine compiles the condition's definition. No further checking occurs at compile time. Only runtime type checking is implemented.
When a condition is executed within a particular request, each function or operator checks the type of each argument it receives. (The RCL does not provide type casting, so you cannot coerce types.) If the type is invalid, the operator returns an error. For example, if a built-in function expects an OCTET STRING and it is passed an INTEGER, it causes the condition to return FALSE.
Note A condition that is syntactically valid but contains an error detected only at runtime acts in the same way as a valid condition that returns FALSE.
The em_debug utility provides facilities for debugging request templates. For information on template debugging, see Chapter 16.
Sun Microsystems, Inc. Copyright information. All rights reserved. |
Doc Set | Contents | Previous | Next | Index |