4. Implementation

NetSpy actually consists of two separate programs - the NetSpy program itself and the DPML-MCS collection service. Using Open Inventor as the 3D graphcis toolkit made C++ the logical choice for NetSpy's implementation. By writing the DPML-MCS collection service in C++ as well, it was possible to share code between the two programs.

The user interface controls included with Inventor are adequate only for manipulating the Inventor scene itself. The design of NetSpy called for other user interface elements to allow for the interactive construction of scenes. The ViewKit class library, available on Silicon Graphics platforms, eases the construction of graphical user interfaces using the Motif widget set for the X Window system. This was the chosen method for the user interface impementation.

4.1 Object Relationships

When the NetSpy program is running it consists of a large number of objects in memory that communicate with each other through clearly defined interfaces.

There are serveral levels of communication between the objects within NetSpy.


Figure 4-1: High level object communication.

Figure 1 shows the highest level of communication between the objects in NetSpy. The Application Object is an instance of the NetSpy class. This is an extension of the ViewKit class VkApp, of which an application using the toolkit must have one and only one instance. The Main Window object is an instance of the NetSpyWindow class, a derivative of the VkWindow class, another ViewKit class which controls the application's main window. NetSpy's menu is created by the Main Window object. Many of the menu selections lead to dialog boxes. These are handled as part of the User Interface objects. The Scene Definition object keeps track of all the information related to the visualization scene and the communication with the various collection services.

In terms of the scene displayed to the user, the communication between the computers being monitored (hosts) and the gadgets, the main object is the Scene Definition object. This is an instance of the SceneDef class. The following diagram shows the relationship between the Scene Definition object and the gadget and host objects.


Figure 4-2: Relationship between Scene Definition and gadgets and hosts.

The Master Gadgets are instances of each type of gadget - there is one object for each type. When a user wishes to create a new shape or arranger gadget, a copy is made from one of the master objects. They are referenced by name: for example, "CityBlock" for the city block (grid) arranger object.

Each gadget in the scene is referenced by the Scene Definition object, as is each host from which statistics are being collected. The Connection objects provide the communication channel between the statistics and the gadgets.

4.2 The Gadget Classes

The different types of gadgets and their definite hierarchical relationship made them a perfect candidate for implementation using an object-oriented approach. An additional benefit of this is that the implementation of the different arrangers and gadgets is simply the specialisation of a defined interface.

The following diagram shows the class hierarchy:


Figure 4-3: Gadget class hierarchy

GadgetBase
The GadgetBase class defines the interface for nearly all of the dervied gadget classes. It also implements as much of the common behaviour as possible, removing the need to re-implement this in the other classes. A couple of important methods and data elements of this class are:

Collection
The Collection class is used for grouping other shape, meta- or collection gadgets into a new gadget. Unfortuneately, time constraints meant that it was not possible to complete implementation of this gadget.

Distributor
The Distributor class is used to link statistics with a gadget. It takes and Arranger object and a shape gadget object and provides a mechanism for doling out the instances of a given statistic to each of the shape objects that it creates (one for each instance). It uses the given Arranger gadget to layout the shape gadgets.

Arranger
Objects of the Arranger class are responsible for the layout of the gadgets within a scene. Arranger is derived from MetaGadget from which it inherits the gadget handling interface and default behaviour. The significant methods implemented by an arranger gadget are:

4.3 Use of Open Inventor

The actual 3D graphics are drawn using the Open Inventor toolkit, a C++ class library designed for the purpose. To display graphics in Inventor it is required to build an Inventor scene (as distinct from a scene in NetSpy), which Inventor renders. An Inventor object called a viewer is used to display the scene on a workstation's screen.

A scene is defined using a scene graph: a graph in which the nodes define certain graphical objects, transformations or other drawing properties. When Inventor renders a scene, the scene graph is traversed in depth first order and the resulting graphical display is built and rendered.

As a simple example, consider the following diagrams:


Figure 4-4: Inventor scene graph and resulting display

The text next to the nodes in the graph on the left are the Inventor node types (class names of objects). The SoSeparator node is the root of this particular scene graph. The SoMaterial node defines a drawing material (colour, surface reflectivity properties) and finally, the SoCone node defines the shape to be drawn.

If it is desired to move an object to a different location within a scene then a transform node must be placed within the graph before the shape in the traversal path. Some of the possible transforms include: SoTranslation, SoRotationXYZ and SoScale which, as their names suggest, perform translation, rotation and scale transformations, respectively.

The SoSeparator node allows the Inventor scene to be constructed as a number of components, each of which is created indepently. It is in this way that the scene graph is built in NetSpy. Each gadget object defines its own small part of the complete scene graph, each starting with a SoSeparator node. For example, the scene graph created by the Cube shape gadget is very similar to the example given above, except that a SoCube node is used instead of SoCone. An arranger gadget, under its own SoSeparator node, introduces the appropriate transform nodes to place the individual gadgets within the scene. The scene graph defined by the Cube gadget would be then be placed into the scene, as in the following diagram:


Figure 4-5: Scene graph constructed by gadgets

4.4 Communication with Collection Services

The process running on a computer to be monitored is called a collection service. These collection services send their information to the NetSpy program using standard network transport protocols. The PMCS defines a proprietry protocol for transporting the information across the network. This protocol has been designed to have as little impact on network traffic as possible.

Programs that make use of PMCS use the PMAPI (Performance Metric Application Programming Interface). The function calls in this interface take care of the intricacies of network communication.

Similarly DPML-MCS defines a protocol for the transport of information across the network. This protocol is documented in Appendix B. The following diagram highlights the various objects in NetSpy and the DPML-MCS collection service that implement the network communicaton.


Figure 4-6: Implementation of collection service to gadget communication.

NetSpy and the collection service share code for the Socket, Metric, Instance, and Value classes. A fellow honours student, Jamie Cameron, generously donated source code which I based the Socket and Server classes on. These classes implement a simple but reliable communication service using standard BSD socket system calls. The Server class provides default behaviour for creating a network service, such as the DPML-MCS collection service.

The Metric class defines the interface for specifying the format of the statistics. This includes their names, the individual instances and their values. A mechanism for translation into the DPML-MCS protocol for transmission, and for translation back again after reception, is similarly defined. Programmer's wishing to use DPML-MCS for sending additional statistics to NetSpy can use these classes to make the job easier, although they are not essential to conform to the protocol.

4.5 User Interface

Implementation of the user interface in NetSpy makes use of two distinct toolkits: Open Inventor and ViewKit. The Open Inventor toolkit is used to create the interface for navigating around the scene. The following screen shot shows the navigation controls in NetSpy.


Figure 4-7: Scene navigation interface

The controls depicted in the above figure are provided by the SoXtExaminerViewer class, a member of the Open Inventor class library.

The menus and dialog boxes that make up the rest of the user interface were implemented using the ViewKit class library. However, it is somewhat incomplete, and in many cases the programmer is required to drop back to the Motif level to create user interface components such as buttons, lists, labels and text fields. To maintain consistency I extended the ViewKit class library so that it contained classes for creating the user interface components mentioned above.

Motif and ViewKit make heavy use of callback procedures. This is in keeping with the event driven nature of graphical user interface design. When the user takes some action an event is passed on to the application program. ViewKit or Inventor handles these events internally and then calls a callback function so that the application can regain control and take the appropriate action.

A good example of this is the pull-down menus. These menus are defined in the NetSpyWindow class, and callback routines are provided for each option in the menus. When the user makes a selection the appropriate callback is invoked - a method of NetSpyWindow in the case of the menus. In this way, when the user selects the "Add host..." option from the "Hosts" menu the addHostCallback() method is invoked, which in turn brings up the "Add New Host" dialog box.

The dialog boxes all make use of the classes in ViewKit derived from the VkDialogManager class. There is a separate class for each different dialog box in NetSpy, with an instance of each class created in the NetSpyWindow object. Most of these dialog boxes make heavy use of the Scene Definition object to obtain lists of the various elements in the current scene and the list of hosts from which statistics are currently collected. When the user selects the "OK" button on a dialog box an addition is typically made to the Scene Definition object. The following diagram illustrates the interaction between the various objects here.


Figure 4-8: Communication between user interface objects

As an example of the dialog boxes created for NetSpy, here is a screen shot of the "New shape..." dialog box:


Figure 4-9: "New shape..." dialog box

The components that make up the dialog box are each an object of a ViewKit, such as VkScolledList for the list of shape or arranger types, or VkRadioBox for the distributor type. The shape name field is a VkText object. Each of these classes implements a query method of the form get...() which is used to retrieve the appropriate value for that type of object. In the case of a VkScrolledList, for example, the method is getSelection() which returns the index to the currently selected item in that list.

4.6 Connections

A connection is the term used to describe how a statistic, once received by a Host object, finds its way to a gadget. This is quite a complex process and is best described using a diagram and an accompanying description.


Figure 4-10: Journey of a statistic to a gadget

Each Host object maintains a list of connections. A connection, an object of the Connection class, maintains a pointer to a statistic (instance of class Metric) and a dispatcher (instance of class Dispatch). When the host object retrieves new data from the collection service it updates all of the statistics. When this is done it gets the ConnectList to update all of the connections using the update() method.

When a Connection object is updated, using its update() method, it passes its statistic (Metric object) to its dispatcher. A dispatcher maintains a reference to a distributor gadget and the name of the degree to which this statistic is attched. When the dispatcher receives a metric it passes it on to the distributor object. As described in the section on gadgets, the distributor then dispenses the individual instances to each of its shape gadgets.

As evident from the above diagram, the distributor is passed a Metric, and the shape gadgets are passed a Value object. This is because a Metric contains a Value for each instance of that statistic collected from the host.


[Table of Contents] [Previous Section] [Next Section]


David Sykes / dsykes@cs.monash.edu.au