Table Of Contents
Getting Started with BQL
What Is BQL?
Quick Start—BQL Basics
Connecting to BQL
Connecting to BQL with SSL
Executing BQL Commands
Device-List Report Example
The BQL Get Command
Trouble-Ticket Registration and User Scope
Getting Started with BQL
What Is BQL?
Broadband Query Language (BQL) is a generic machine interface language, implemented by the Cisco ANA gateway, for general-purpose northbound integration. BQL covers all Cisco ANA functionality:
•
Information reporting (such as inventory, topology, or fault)
•
Service activation
•
System administration
The interface is based on XML messages over TCP sockets. All data sent to and returned from the system is formatted as XML messages, containing IMO (Cisco's internal information model) data objects.
Quick Start—BQL Basics
This section briefly describes the BQL interface and gives an example of how to use it for integration. Topics include:
•
Connecting to BQL
•
Connecting to BQL with SSL
•
Executing BQL Commands
•
Device-List Report Example
•
The BQL Get Command
These topics include sample software programs, written in Perl. However, BQL is not restricted to any specific programming language.
Connecting to BQL
The BQL interface uses a TCP socket transport. The Cisco ANA gateway listens for incoming connection attempts on a well known port, as follows:
•
Protocol—TCP
•
Port number—9002
•
Socket type—Streamable
To open a BQL session, the connecting application must authenticate the session using a username and password (which has been previously defined within the Cisco system). The authentication command is:
openconnection user=<Username> password=<Password>
When a BQL session is opened, the scopes associated with the user profile are applied to the session. For more information about user scopes, see Cisco Active Network Abstraction User Guide 3.6 Service Pack 4 on Cisco.com.
Following is a Perl example of opening and authenticating a BQL session, with a Cisco ANA gateway whose IP address is 192.168.2.110:
my $sock = IO::Socket::INET->new(PeerAddr => '192.168.2.110',
die "Cannot open socket" unless defined $sock;
print $sock "openconnection user='John' password='XYZ'\n.\n";
while (($Recv=<$sock>)!~ /^\./)
if ($Recv =~ /.*success.*/)
Note
The \n.\n end-of-text (EOT) sequence at the end of commands is explained in Executing BQL Commands.
To disconnect from the BQL interface, enter the command:
Then close the connection to the Cisco ANA gateway.
Connecting to BQL with SSL
The BQL interface uses Secure Socket Layer (SSL) transport. The Cisco ANA gateway listens for incoming connection attempts on a well known port, as follows:
•
Protocol—SSL
•
Port number—9003
•
Socket type—Streamable
To open a BQL session, see Connecting to BQL.
Executing BQL Commands
After the BQL session is authenticated, all commands and responses are formatted as plain-text XML messages. Each command has the following format:
<command name="commandName">
<param name="paramName1">
<value>ParamValue1</value>
<param name="paramName2">
<value>ParamValue2</value>
Every command must end with an EOT sequence, which is a <NewLine> character ("\n") followed by a dot in an empty line, as follows:
EOT:"\n.\n"
Therefore, every command has the format:
<command name="commandName">
The EOT sequence also terminates all BQL replies. However, when receiving unsolicited notifications, the EOT sequence changes to the format:
Notification EOT:"\n$\n"
Notifications are further explained in the section Specifying Properties vs. Aspects, page 21-17.
The following example demonstrates a BQL command that retrieves the list of all NEs managed by the system. The command is DeviceList and has no parameters:
<command name="DeviceList">
After sending this command to the BQL socket, the socket connection is blocked until the Cisco ANA gateway finishes processing the query. Once finished, the Cisco ANA gateway responds with the list of all devices in the system and frees the connection for further queries. The reply to the DeviceList command is, for example, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<ID type="Oid">{[ManagedElement(Key=CBX500Lab)]}</ID>
<CommunicationStateEnum type="Integer">3</CommunicationStateEnum>
<DeviceName type="String">CBX500Lab</DeviceName>
<ElementCategoryEnum type="Integer">2</ElementCategoryEnum>
<ElementTypeEnum type="Integer">22</ElementTypeEnum>
<IP type="com.sheer.types.IPAddress">192.168.2.70</IP>
<InvestigationStateEnum type="Integer">2</InvestigationStateEnum>
<SoftwareVersion type="String">04.02.01.00</SoftwareVersion>
<SysContact type="String" />
<SysDescription type="String">Lucent Technologies CBX 500</SysDescription>
<SysLocation type="String" />
<SysName type="String">cbx500f</SysName>
<SysUpTime type="java.util.Date">Wed Apr 30 16:17:04 IDT 2003</SysUpTime>
<VendorEnum type="Integer">6</VendorEnum>
<ID type="Oid">{[ManagedElement(Key=CBX_Sim_Iftach)]}</ID>
<CommunicationStateEnum type="Integer">3</CommunicationStateEnum>
<DeviceName type="String">CBX_Sim_Iftach</DeviceName>
<ElementCategoryEnum type="Integer">2</ElementCategoryEnum>
<ElementTypeEnum type="Integer">22</ElementTypeEnum>
<IP type="com.sheer.types.IPAddress">30.30.30.70</IP>
<InvestigationStateEnum type="Integer">2</InvestigationStateEnum>
<SoftwareVersion type="String">04.02.01.00</SoftwareVersion>
<SysContact type="String" />
<SysDescription type="String">Lucent Technologies CBX 500</SysDescription>
<SysLocation type="String" />
<SysName type="String">cbx500f</SysName>
<SysUpTime type="java.util.Date">Mon May 05 16:16:51 IDT 2003</SysUpTime>
<VendorEnum type="Integer">6</VendorEnum>
This XML reply represents a list of two devices (two Lucent CBX switches, with IP addresses 192.168.2.60 and 30.30.30.70). The data objects in the reply are based on the IMO, which is the Cisco-internal, generic information model. The list is an array of IMO objects of type IManagedElement (the IMO object that represents an NE).
Each data entity type in the Cisco system has a corresponding IMO object type, which is serialized by BQL into XML strings. The full set of all IMO objects is described in the IMO Reference Manual. See Chapter 20, "Understanding IMO" and Chapter 21, "IMO Specification" for further descriptions of IMO.
Device-List Report Example
The following is a full Perl example for retrieving a device list:
# ------- Open a BQL session
my $sock = IO::Socket::INET->new(PeerAddr => '192.168.2.110',
die "Cannot open socket" unless defined $sock;
print $sock "openconnection user='John' password='XYZ'\n.\n";
while (($Recv=<$sock>)!~ /^\./)
if ($Recv =~ /.*success.*/)
# ----- Send command and retrieve reply
print $sock "<command name='DeviceList'></command>\n.\n";
while (($Recv=<$sock>) !~ /^\./ )
$Result = $Result . $Recv;
The reply to the BQL command is returned from the Cisco ANA gateway socket as a data stream. Therefore, the program has to run a loop of reading from the socket into the temporary variable $Recv, and concatenating it into the result variable $Result.
The BQL Get Command
The most commonly used BQL command is the GET command. It specifies the object identifier (OID) of a data entity in the system and returns the information on this object. The OID uniquely identifies any data entity in the system. The GET command can be used not only for reporting a single object, but also for reporting a construct of objects, which is a hierarchy of related data objects (for example, an NE with all of its cards and ports, or an end-to-end service path). When retrieving data constructs, the specified OID serves as the "root" of the construct, from which the related objects are traversed.
Following is an example of a simple GET command:
<value>{[ManagedElement(Key=Fore251Lab)]}</value>
<key name="DeviceProperties">
<key name="requiredProperties">
The query in this example retrieves the properties of the NE identified by the OID {[ManagedElement(Key=Fore251Lab)]}. The query has an additional parameter, the Retrieval Specification (RS). The RS defines the information scope of the query, by specifying the type of IMO objects to retrieve, the object relationships to traverse, and the properties to include or exclude for each returned object.
The RS is an XML string with the format:
<entry name="register">[true/false]</entry>
<key name="requiredProperties">
<key name=[* or IMO type]>
<entry name=[* or property name]/>
<entry name=[* or property name]/>
<key name="excludedProperties">
<key name=[* or IMO type]>
<entry name=[* or property name]/>
<entry name=[* or property name]/>
For example:
<key name="DeviceProperties">
<key name="requiredProperties">
<key name="com.sheer.imo.IManagedElement">
In this example the RS specifies the retrieval of only the device properties (such as IP address, type, vendor, and uptime).
The output of the above BQL GET example (device properties of the network element whose key is "Fore251Lab") looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<ID type="Oid">{[ManagedElement(Key=Fore251Lab)]}</ID>
<CommunicationStateEnum type="Integer">3</CommunicationStateEnum>
<DeviceName type="String">Fore251Lab</DeviceName>
<ElementCategoryEnum type="Integer">2</ElementCategoryEnum>
<ElementTypeEnum type="Integer">13</ElementTypeEnum>
<IP type="com.sheer.types.IPAddress">192.168.2.251</IP>
<InvestigationStateEnum type="Integer">2</InvestigationStateEnum>
<LogicalRoot type="ILogicalRoot">
<ID type="Oid">{[ManagedElement(Key=Fore251Lab)][LogicalRoot]}</ID>
<PhysicalRoot type="IPhysicalRoot">
<ID type="Oid">{[ManagedElement(Key=Fore251Lab)][PhysicalRoot]}</ID>
<ProvisioningSupportedServices type="java.lang.String_Array">
<java.lang.String>256_ILink</java.lang.String>
<java.lang.String>384_Bizlink</java.lang.String>
<java.lang.String>GSHDSL_256K_cbr</java.lang.String>
/ProvisioningSupportedServices>
<SoftwareVersion type="String">S_ForeThought_7.0.0 FCS-Patch
(1.101625)</SoftwareVersion>
<SysContact type="String">eli11</SysContact>
<SysDescription type="String">Marconi ASX-1000</SysDescription>
<SysLocation type="String">Sheer-labs</SysLocation>
<SysName type="String">ATM SWITCH</SysName>
<SysUpTime type="java.util.Date">Mon Apr 14 13:00:50 IDT 2003</SysUpTime>
<VendorEnum type="Integer">5</VendorEnum>
The RS allows registering for change notifications on the specified objects. When you specify register=true in the RS, the Cisco ANA platform monitors changes in all objects that are defined in the RS scope. Whenever it detects a change in any of the objects, it sends an unsolicited notification of the change. Consider, for example, the following notification:
<?xml version="1.0" encoding="UTF-8"?>
<ID type="Oid">{[Notification(SequenceNumber=1201)(Time=1052837316305)]}</ID>
<PropertyName type="String">SysName</PropertyName>
<NewIMO type="IManagedElement">
<ID type="Oid">{[ManagedElement(Key=ASAMLab)]}</ID>
<SysName type="String">ATM Switch</SysName>
This notification indicates that the property SysName has changed, in the IMO object of type IManagedElement, of the NE "ASAMLab". Further details on RSs and notifications can be found in the sections Retrieval Specifications, page 21-9 and Specifying Properties vs. Aspects, page 21-17.
Figure 19-1 summarizes the integration sequence using the BQL.
Figure 19-1 Integration Sequence
The following lists the tasks in the integration sequence:
1.
Open a TCP socket to the BQL interface.
2.
Authenticate using username and password.
3.
Send BQL commands to the Cisco ANA gateway.
4.
Receive and parse the returned results.
5.
(Optional) Register and receive change notifications.
6.
Close the connection to the BQL interface.
Trouble-Ticket Registration and User Scope
A BQL registration can support another registration. For example, consider the following BQL query:
<command name="GetAllTickets">
<value>{[AlarmList]}</value>
<entry name="depth">0</entry>
<entry name="register">true</entry>
<entry name="cachedResultAcceptable">false</entry>
<key name="requiredProperties">
This query asks for all alarms generated by devices that are assigned to the user who is connected to BQL. However, this list of devices may change; for example, when a scope that the user has assigned is updated. In this case, it is helpful to register for changes in the scopes as shown in the following example:
<value>{[Scope(Name=putScopeNameHere)]}</value>
<entry name="depth">0</entry>
<entry name="register">true</entry>
<entry name="cachedResultAcceptable">false</entry>
<key name="requiredProperties">
<key name="com.sheer.imo.IScope">
We recommend that you issue a command similar to this for each scope that the connected user has. In this way, whenever any one of the scopes changes, the BQL client receives an event indicating that the original registration should be removed and the new one applied to reflect the user's new scope. After this, the user can run the query again.