Novell is now a part of Micro Focus

How to Monitor NetWare Servers Using a Wireless Device

Articles and Tips: article

J. Jeffrey Hanson
Senior eBusiness Architect
Financial Fusion
jhanson583@aol.com

01 Mar 2001


This article discusses how network administrators can use Java components shipped by Novell to design and implement network server administration utilities that can be used from a Web browser or from a wireless device.

Introduction

A network administrator's job can be a difficult and stressful one. The very life of a company often times depends on the ability of the IS&T staff to keep the network running efficiently. As more and more devices and services become connected, the responsibilities facing network administrators are increasing exponentially. This is forcing companies to face the need to either increase their IS&T staff size significantly or to make their existing staff much more efficient. In this AppNote, we focus on making an IS&T staff more efficient by allowing them to be virtually more than one place at a time using Novell's tools and wireless technologies.

This AppNote will demonstrate how network administrators can use Java components shipped by Novell to design and implement network server administration utilities that can be used from a Web browser or from a wireless device. We will work within a three-tier architecture, using Java server-side technologies such as servlets and Java Beans to perform command dispatching and business logic on the middle tier, and Java Beans to access data on the back end. We will be using Java Beans, HTML, HDML and WML within Java Server Pages (JSPs) to construct the user interface. We will use the model-view-controller (MVC) design pattern to avoid inter-code dependencies, isolate bug fixing, and enable new features and enhancements to be easily implemented using "plug-in" style techniques. We assume that the reader is familiar with servlet and JSP technologies.

Abstracting Design to Avoid Device Dependency

Novell ships a suite of Java components called "MVC Beans for eBusiness" that provide access to detailed server data. They are also optimized for Web application development using the MVC design pattern. These components will be used to implement our business logic, data access, and user interface.

Our applications will begin with an HTTP command/request passed from a client, such as a Web browser or wireless device, to a Web server or Web application server. The server is where our business logic components will be used for command/request handling and our data access components will be used for accessing server data. Our user interface components will then be used to form the response as HTML, HDML, or WML and passed back to the Web browser or wireless device. We can abstract this interaction between the client and server using the model-view-controller (MVC) pattern.

The command/request will be handled by a servlet residing within the Web application environment. This servlet acts as the controller of our Web application. The controller-servlet reacts to the command/ request by dispatching it to Java Beans known as "command" beans. The command beans expose the model of our application and shoulder the responsibility of performing the business logic for the command/request and retrieving data for the client. The controller- servlet then uses JSP and Java Beans to format the response, which is passed to the client in the form of HTML, HDML ,or WML. The combination of JSP and Java Beans compose the view portion of our application.

Novell's MVC Beans for eBusiness provide command beans as well as controller servlets to form the base framework for many types of domains. In the examples that follow, we will be using Novell's OS Server command beans to perform several kinds of network server administration duties.

Configuring the Server for Wireless Access

Our application will use Java servlets to handle requests coming in from clients. In order to respond to requests made from wireless devices, we must configure our application server environment to handle mime types defined for HDML and WML. Before we look at the steps to take to configure for these mime types, let's familiarize ourselves with WML and HDML.

WML

WML is based on XML. XML provides the ability to define any arbitrary set of tags desired. The set of tags is grouped into a Document Type Definition, or DTD. The DTD used to define WML is located at http://www.wapforum.org/DTD/ wml_1.1.xml. A WML-enabled phone or other wireless device understands how to handle all tags in the WML DTD.

A WML-page is actually called a Deck. Every Deck contains one or more Cards. Cards contain a set of elements that display text, display images, respond to events, gather user input, and so on. (We will not discuss the details of these elements here.) WML files have an extension of .WML.

The following examples demonstrate a couple of typical WML cards.

Simple Example

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml> 
<card id="FirstCard" title="Simple Example"> 
   <p>
      <!-This is a comment --> 
      This will be displayed on the phone. 
   </p> 
</card> 
</wml>

More Complex Example

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
   
<wml>
<card id="Logon" title="Logon">
   <do type="accept" label="Logon">
      <go href="http://www.myserver.com/authenticate"/>
   </do>
   <p>
      UserName:
      <select name="username" title="User Name:">
         <option value="John Doe">John Doe</option>
         <option value="Jane Doe">Jane Doe</option>
         <option value="Joe Smith">Joe Smith</option>
         <option value="Jane Smith">Jane Smith</option>
      </select>
   </p>
   <p>
      Password: <input type="text" name="password"/>
   </p>
</card>
</wml>

You must register the proper MIME types with your Web server so that WML content can be properly processed. The MIME types that need to be registered are listed in the following table.


Content
MIME type
File Extension

WML document

text/vnd.wap.wml

.wml

Wireless Bitmap Image

image/vnd.wap.wbmp

.wbmp

WMLScript

text/vnd.wap.wmlscript

.wmls

Compiled WML document

application/vnd.wap.wmlc

.wmlc

Compiled WML Script

application/vnd.wap.wmlscriptc

.wmlsc

The way you configure MIME types is different for disparate Web servers. For example, here's how to configure them in Apache or IBM's HTTP Server.

First, locate the srm.conf file (typically found in /etc/httpd/conf), or .htaccess files in the directory or directories that you require. Then type in the following:

# WAP MIME Types AddType text/vnd.wap.wml .wml AddType image/vnd.wap.wbmp .wbmp AddType text/vnd.wap.wmlscript .wmls AddType application/vnd.wap.wmlc .wmlc AddType application/vnd.wap.wmlscriptc .wmlsc

Save the file and restart Apache.

HDML

As with WML, HDML is defined by Decks and Cards. HDML currently supports the following types of cards:

  • Display Cards, which are used to display information

  • Non-Display Cards, which are used to execute actions but do not appear on the display of the device

  • Entry Cards,which are used to display messages and allow a user to enter text

  • Choice Cards, which are used to display a list of options from which the user can choose

A Deck is the smallest unit of HDML a service can send to a phone. A Deck can contain one Card or multiple Cards. When an HDML- enabled phone receives a Deck, it processes the first Card it finds in the Deck. The phone then displays the information in the Card and allows the user provide a response.

The following example demonstrates a simple HDML deck with one Display Card.

<HDML VERSION="3.0"> 
   <DISPLAY> 
            Hello World! 
   </DISPLAY>
</HDML>

To provide an HDML service on your Web server, you must configure your Web server to serve HDML. Specifically, you must configure it to support the following MIME types and extensions:


Content
MIME type
File Extension

HDML Document

text/x-hdml

hdml

Bitmap Image

image/bmp

bmp

Connecting to the Server

Novell's MVC Beans for eBusiness provide a set of OS Command Beans that work on any NetWare 5.1 server. Connecting to the server becomes a function of the client-to-server communication and the authentication and authorization mechanisms available on the server. NDS is a highly optimized and secure service for authenticating users and obtaining access-control information, allowing administrators to easily authorize a user for each intended task. Novell's MVC Beans for eBusiness provide a comprehensive set of Beans that provide access to NDS and user authentication information. Securing an over-the-air wireless transaction is accomplished with the Wireless Transport Layer Security (WTLS), wireless versions of PKI, Dynamic Proxy Navigation (DPN), and other technologies. We won't discuss these technologies in this document.

The following examples demonstrate how an administrator can authenticate a user and access authorization information for the user to control access to secured resources on the server:

import javax.servlet.*;
import javax.servlet.http.*;

public class MyEDirServlet extends HttpServlet
{
   private com.novell.web.command.beans.edir.AuthenticateEDir authBean = null;
   private String treeName = "";
   private String context = "";
   private String userID = "";
   private String password = "";
   
   public void doPost(HttpServletRequest req,
                  HttpServletResponse res)
         throws ServletException, IOException
   {
         doGet(req, res);
   }
   
      public void doGet(HttpServletRequest request,
                     HttpServletResponse response)
         throws ServletException, IOException
      {
         // if session is new, we need to respond to the client and request the
         // authentication credentials
         if ((authBean == null) && (getCredentials() == false)) {
            writeAuthenticationResponse(response);
            return;
   }
         if ((authBean = doAuthentication(treeName,
                        context,
                        userID,
                        password)) == null) 
      {
            throw new ServletException("Invalid userID and/or password");
      }
   
      storeSessionValues(request);
      callJSPPage(request, response);
   }
}
   
boolean getCredentials(HttpServletRequest request)
{
   // test credentials retrieved from query parameters and return boolean
   // flag accordingly
   if ((treeName = request.getParameter("TREE_NAME")) == null) {
      return(false);
   }
   if ((context = request.getParameter("CONTEXT")) == null) {
      return(false);
   }
   if ((userID = request.getParameter("USER_ID")) == null) {
      return(false);
   }
   if ((password = request.getParameter("PASSWORD")) == null) {
      return(false);
   }
   
   return(true);
}
   
void writeAuthenticationResponse(HttpServletResponse response)
{
   // This method is where the programmer can decide what kind of 
   // authentication mechanism is required and what kind of response
   // to pass to the client.
   // The different mechanisms can be basic authentication, certificate
   // authentication, custom HTML forms, custom WML Cards, etc.
}
   
void callJSPPage(HttpServletRequest request,
               HttpServletResponse response)
         throws ServletException, IOException
{
ServletContext ctx = getServletContext();
   ctx.getRequestDispatcher("/mymainpage.jsp").forward(request,
                              response);
}

When we establish the fact that we are working with a new client and that the authentication credentials have been passed to our servlet, we attempt to authenticate the client as follows:

public com.novell.web.command.beans.edir.AuthenticateEDir doAuthentication
   (String treeName,
   String context,
   String userName,
   String password)
   {
      com.novell.web.command.beans.edir.AuthenticateEDir authBean =
            new com.novell.web.command.beans.edir.AuthenticateEDir();
      authBean.setTreeName(treeName);
      authBean.setUserContext(context);
      authBean.setUserID(userName);
      authBean.setUserPassword(password);
   
      try {
         authBean.perform();
         return authBean;   // user authentication succeeded
      } catch(com.novell.web.command.CommandException e) {
      }
   
      return null;  // user authentication failed
   }

When we are ready to end our session with a user, we use the UnauthenticateEDir command bean to un-authenticate the user. We do this by passing the saved AuthenticateEDir bean in as the only input property of the AuthenticateEDir command bean, then we call the perform method on the bean as follows:

public void doUnauthentication(AuthenticateEDir authBean)
   throws ServletException
{
   com.novell.web.command.beans.edir.UnauthenticateEDir   cmdBean =
   new com.novell.web.command.beans.edir.UnauthenticateEDir();
   cmdBean.setAuthenticatedObject(authBean);
   
   try {
      cmdBean.perform();
   } catch(com.novell.web.command.CommandException e) {
      throw new ServletException(e.toString());
   }
}

Maintaining State for Each User

Since the HTTP protocol is stateless (that is, it does not maintain state across multiple requests from the same user), we need a way to preserve the state of the user's session. We do this by exploiting the state-saving mechanism presented to us by the HttpSession object. The HttpSession object is retrieved from the request object. Once we retrieve the session object, we can use it to store objects containing any arbitrary data that we need to keep track of during our session with each client.

The following example demonstrates how to retrieve the session object and use it to store an instance of the AuthenticateEDir bean:

void storeSessionValues(HttpServletRequest request)
{
   HttpSession session = getSession(request);
// Objects are stored as name/value pairs
   session.putValue("authBean", authBean);
}
   
HttpSession getSession(HttpServletRequest request)
{
   HttpSession   session = null;

   if (request.isRequestedSessionIdValid()) {
      session = request.getSession(false);
   } else {
      session = request.getSession(true);
   }
}

Monitoring Connections

A network administrator must manage the connection usage for each server in order to better distribute the workload for a particular network or Web site. The following examples demonstrate how an administrator can collect information concerning connection usage in order to make smart decisions concerning traffic distribution and workload management.

List Current Connections

<%
   com.novell.web.command.beans.os.ListConnections   cmdBean =
            new com.novell.web.command.beans.os.ListConnections();
   
try {
   cmdBean.perform();
%>
   <p>Connections:</p>
<%
String[]   names = cmdBean.getNames();
if (names != null) {
for (int i = 0; i < names.length; i++) {
%>
         <p><%=names[i]%></p>
<%
}
}
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Count Current Connections

<%
com.novell.web.command.beans.os.CountCurrentConnections   cmdBean =
         new com.novell.web.command.beans.os.CountCurrentConnections();
   
try {
cmdBean.perform();
%>
<p>Connection count: <%=cmdBean.getCount()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Clear Connections That Are Not Currently Logged in

<%
com.novell.web.command.beans.os.ClearAllNotLoggedInConnections   cmdBean =
      new com.novell.web.command.beans.os.ClearAllNotLoggedInConnections();
   
try {
cmdBean.perform();
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Broadcast a Message to a Connection

<%
com.novell.web.command.beans.os.BroadcastMessageToConnection   cmdBean =
      new com.novell.web.command.beans.os.BroadcastMessageToConnection();
cmdBean.setConnectionName("Admin");
cmdBean.setMessage("How much wood can a woodchuck chuck?");
try {
cmdBean.perform();
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Broadcast a Message to All Current Connections

<%
com.novell.web.command.beans.os.BroadcastMessageToAll   cmdBean =
         new com.novell.web.command.beans.os.BroadcastMessageToAll();
cmdBean.setMessage("Now is the time for all good men...");
   
try {
cmdBean.perform();
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Clear One Connection

<%
com.novell.web.command.beans.os.ClearConnection   cmdBean =
            new com.novell.web.command.beans.os.ClearConnection();
cmdBean.setConnectionName("NOT_LOGGED_IN");
   
try {
cmdBean.perform();
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the ID for a Connection

<%
com.novell.web.command.beans.os.GetConnectionID   cmdBean =
            new com.novell.web.command.beans.os.GetConnectionID();
cmdBean.setConnectionName("Admin");
   
try {
cmdBean.perform();
%>
<p>Connection ID: <%=Integer.toHexString(cmdBean.getID())%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Number of a Connection

<%
com.novell.web.command.beans.os.GetConnectionNumber   cmdBean =
            new com.novell.web.command.beans.os.GetConnectionNumber();
cmdBean.setConnectionName("Admin");
   
try {
cmdBean.perform();
%>
<p>Connection Number: <%=Integer.toHexString(cmdBean.getNumber())%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the State of a Connection

<%
com.novell.web.command.beans.os.GetConnectionState   cmdBean =
            new com.novell.web.command.beans.os.GetConnectionState();
cmdBean.setConnectionName("Admin");
   
try {
cmdBean.perform();
%>
<p>Connection State: <%=cmdBean.getState()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Type of a Connection

<%
com.novell.web.command.beans.os.GetConnectionType   cmdBean =
            new com.novell.web.command.beans.os.GetConnectionType();
cmdBean.setConnectionName("Admin");
   
try {
cmdBean.perform();
%>
<p>Connection Type: <%=cmdBean.getType()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Number of Connections Allowed

<%
com.novell.web.command.beans.os.GetMaxConnectionsCount   cmdBean =
         new com.novell.web.command.beans.os.GetMaxConnectionsCount();
   
try {
cmdBean.perform();
%>
<p>Max Connections Count: <%=""+cmdBean.getCount()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Test to See If a Connection Is Currently Logged in

<%
com.novell.web.command.beans.os.IsConnectionLoggedIn   cmdBean =
            new com.novell.web.command.beans.os.IsConnectionLoggedIn();
cmdBean.setConnectionName("Admin");
   
try {
cmdBean.perform();
%>
<p>Is Connection Logged In? <%=""+cmdBean.getResult()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Address of a Connection

<%
com.novell.web.command.beans.os.GetConnectionAddress   cmdBean =
         new com.novell.web.command.beans.os.GetConnectionAddress();
cmdBean.setConnectionName("Admin");
   
try {
cmdBean.perform();
}%>
<p>Connection Address: <%=cmdBean.getAddress()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Monitoring Memory

Server memory is a primary concern of a network administrator. Application performance is greatly affected by the available free memory. The following examples demonstrate how to track various aspects of server memory usage which will, in turn, allow better decisions to be made as to application distribution.

Retrieve the VM Page Count for an Address Space

<%
com.novell.web.command.beans.os.GetAddressSpaceLoadedVMPageCount   cmdBean =
      new com.novell.web.command.beans.os.GetAddressSpaceLoadedVMPageCount();
cmdBean.setAddressSpaceName("Java_Kernel_Space");
   
try {
cmdBean.perform();
%>
<p>Loaded VM Page Count: <%=""+cmdBean.getLoadedVMPageCount()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
   }
%>

Retrieve the Locked Page Count for an Address Space

<%
com.novell.web.command.beans.os.GetAddressSpaceLockedPageCount   cmdBean =
      new com.novell.web.command.beans.os.GetAddressSpaceLockedPageCount();
cmdBean.setAddressSpaceName("OS");
   
try {
cmdBean.perform();
%>
<p>Locked Page Count: <%=""+cmdBean.getLockedPageCount()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Retrieve the Mapped Page Count for an Address Space

<%
com.novell.web.command.beans.os.GetAddressSpaceMappedPageCount   cmdBean =
      new com.novell.web.command.beans.os.GetAddressSpaceMappedPageCount();
cmdBean.setAddressSpaceName("OS");
   
try {
cmdBean.perform();
%>
<p>Mapped Page Count: <%=""+cmdBean.getMappedPageCount()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

List the Swap Files for a Volume

<%
com.novell.web.command.beans.os.GetVolumeSwapFiles   cmdBean =
            new com.novell.web.command.beans.os.GetVolumeSwapFiles();
cmdBean.setVolumeName("SYS");
   
try {
cmdBean.perform();
%>
<p>Volume Swap Files:</p>
<%
int[]   indexes = cmdBean.getIndexes();
if (indexes != null) {
for (int i = 0; i < indexes.length; i++) {
%>
      <p><%=""+indexes[i]%></p>
<%
}
}
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Retrieve the Swap File Data for a Volume

<%
com.novell.web.command.beans.os.GetVolumeSwapFileInfo   cmdBean =
         new com.novell.web.command.beans.os.GetVolumeSwapFileInfo();
cmdBean.setVolumeName("SYS");
cmdBean.setIndex(0);
   
try {
cmdBean.perform();
%>
<p>VolumeSize: <%=""+cmdBean.getVolumeSize()%></p>
<p>VolumeFreeSpace: <%=""+cmdBean.getVolumeFreeSpace()%></p>
<p>SwapFileSize: <%=""+cmdBean.getSwapFileSize()%></p>
<p>SwapUsed: <%=""+cmdBean.getSwapUsed()%></p>
<p>SwapMin: <%=""+cmdBean.getSwapMin()%></p>
<p>SwapMax: <%=""+cmdBean.getSwapMax()%></p>
<p>SwapMinFree: <%=""+cmdBean.getSwapMinFree()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Monitoring CPU Usage

A network administrator needs to be able to monitor the workload being applied against a given CPU for a given server and distribute traffic as needed to keep the CPU of the server working as efficiently as possible. The following examples provides information to the administrator about the CPU to help the administrator decide when traffic redistribution is needed.

Retrieve Free Receive Buffer Count for a CPU

<%
com.novell.web.command.beans.os.GetHealthStatValue   cmdBean =
         new com.novell.web.command.beans.os.GetHealthStatValue();
cmdBean.setHealthStatName("perCpuFreeRcvBufferCnt");
   
try {
cmdBean.perform();
%>
<p>CPU Free Receive Buffer Count: <%=""+cmdBean.getValue()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Monitoring Volume Information

Another vital responsibility of a network administrator is monitoring the volume information pertaining to each server and using the capabilities of each volume as efficiently as possible. Distributed/ Web development depends more and more on being able to distribute workload across servers and volumes. The following examples demonstrate beans and services that enable network administrators to obtain information about the volumes of a given server in order to make decisions concerning workload, volume-size modifications, and so on.

List Volumes

<%
com.novell.web.command.beans.os.ListVolumes   cmdBean =
            new com.novell.web.command.beans.os.ListVolumes();
   
try {
cmdBean.perform();
%>
<p>Volumes:</p>
<%
String[]   names = cmdBean.getNames();
if (names != null) {
for (int i = 0; i < names.length; i++) {
%>
      <p><%=names[i]%></p>
<%
}
}
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

List Partition Segments for a Volume

<%
com.novell.web.command.beans.os.GetVolumePartitionSegments   cmdBean =
         new com.novell.web.command.beans.os.GetVolumePartitionSegments();
cmdBean.setVolumeName("SYS");
   
try {
cmdBean.perform();
%>
<p>Volume Partition Segments:</p>
<%
String[]   names = cmdBean.getNames();
if (names != null) {
for (int i = 0; i < names.length; i++) {
%>
      <p><%=names[i]%></p>
<%
}
}
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Retrieve Volume Partition Segment Data

<%
com.novell.web.command.beans.os.GetVolumePartitionSegmentInfo   cmdBean =
      new com.novell.web.command.beans.os.GetVolumePartitionSegmentInfo();
cmdBean.setVolumeName("SYS");
cmdBean.setPartitionSegmentName("DOS Partitioned Media");
   
try {
cmdBean.perform();
%>
<p>Number: <%=""+cmdBean.getNumber()%>;</p>
<p>Type: <%=cmdBean.getType()%></p>
<p>Owner: <%=""+cmdBean.getOwner()%></p>
<p>Capacity: <%=""+cmdBean.getCapacity()%></p>
<p>SlotNumber: <%=""+cmdBean.getSlotNumber()%></p>
<p>PartitionType: <%=""+cmdBean.getPartitionType()%></p>
<p>PartitionID: <%=""+cmdBean.getPartitionID()%></p>
<p>PartitionSizeMB: <%=""+cmdBean.getPartitionSizeMB()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Monitoring General Server Health

Network administrators must be able to respond to server problems without delay. Using wireless communications enables network administrators to respond to server problems as they happen no matter where the server is located. The following examples demonstrate how to monitor the health of various aspects of individual servers.

Get the Health of the Allocated Server Processes

<%
com.novell.web.command.beans.os.GetAllocatedServerProcessesHealth   cmdBean =
   new com.novell.web.command.beans.os.GetAllocatedServerProcessesHealth();
   
try {
cmdBean.perform();
%>
<p>Allocated Server Processes Health: <%=cmdBean.getHealth()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Cache Buffer

<%
com.novell.web.command.beans.os.GetCacheBufferHealth   cmdBean =
         new com.novell.web.command.beans.os.GetCacheBufferHealth();
   
try {
cmdBean.perform();
%>
<p>Cache Buffer Health: <%=cmdBean.getHealth()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Cache

<%
com.novell.web.command.beans.os.GetCacheHealth   cmdBean =
            new com.novell.web.command.beans.os.GetCacheHealth();
   
try {
cmdBean.perform();
%>
<p>Cache Health: <%=cmdBean.getHealth()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Directory Cache

<%
com.novell.web.command.beans.os.GetDirectoryCacheHealth   cmdBean =
         new com.novell.web.command.beans.os.GetDirectoryCacheHealth();
   
try {
cmdBean.perform();
%>
<p>Directory Cache Health: <%=cmdBean.getHealth()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Directory Entries

<%
com.novell.web.command.beans.os.GetDirectoryEntriesHealth   cmdBean =
         new com.novell.web.command.beans.os.GetDirectoryEntriesHealth();
   
try {
cmdBean.perform();
%>
<p>Directory Entries Health: <%=cmdBean.getHealth()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Disk Space

<%
com.novell.web.command.beans.os.GetDiskSpaceHealth   cmdBean =
         new com.novell.web.command.beans.os.GetDiskSpaceHealth();
   
try {
cmdBean.perform();
%>
<p>Disk Space Health: <%=cmdBean.getHealth()%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Disk Throughput

<%
com.novell.web.command.beans.os.GetDiskThroughputHealth   cmdBean =
         new com.novell.web.command.beans.os.GetDiskThroughputHealth();
   
try {
long   startTime = System.currentTimeMillis();
long   currTime = startTime;
long   lastTime = startTime;
int    peak = 0;
int    current = 0;
while (currTime < (startTime + 30000)) {
cmdBean.reset();
cmdBean.perform();
com.novell.beans.NWSrvOS.NWSrvOS   srvOSBean =
new com.novell.beans.NWSrvOS.NWSrvOS();
com.novell.beans.NWSrvOS.HealthStats   healthStats =
srvOSBean.getHealthStats();
com.novell.beans.NWSrvOS.HealthStat   currentThroughput =
healthStats.getElement("currentDiskThroughput");
com.novell.beans.NWSrvOS.HealthStat   peakThroughput =
healthStats.getElement("peakDiskThroughput");
int   currentTmp = currentThroughput.getValue();                              
int   peakTmp = peakThroughput.getValue();                             
if ((currentTmp != current) ||
(peakTmp > peak)) {
%>
      <p>Disk Throughput Health: <%=cmdBean.getHealth()%></p>
<%
}
if (currentTmp != current) {
current = currentTmp;
%>
      <p>Current Throughput: <%=""+current%></p>
<%
}
if (peakTmp > peak) {
peak = peakTmp;
%>
      <p>Peak Throughput: <%=""+peak%></p>
<%
}
currTime = System.currentTimeMillis();
}
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the DS Threads

<%
com.novell.web.command.beans.os.GetDSThreadsHealth   cmdBean =
         new com.novell.web.command.beans.os.GetDSThreadsHealth();
   
try {
cmdBean.perform();
%>
<p>DS Threads Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Event Control Blocks

<%
com.novell.web.command.beans.os.GetECBHealth   cmdBean =
            new com.novell.web.command.beans.os.GetECBHealth();
   
try {
cmdBean.perform();
%>
<p>ECB Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the LAN Traffic

<%
com.novell.web.command.beans.os.GetLANTrafficHealth   cmdBean =
            new com.novell.web.command.beans.os.GetLANTrafficHealth();
   
try {
cmdBean.perform();
%>
<p>LAN Traffic Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Processor Utilization

<%
com.novell.web.command.beans.os.GetProcessorUtilizationHealth   cmdBean =
      new com.novell.web.command.beans.os.GetProcessorUtilizationHealth();
   
try {
cmdBean.perform();
%>
<p>Processor Utilization Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Receive Buffers

<%
com.novell.web.command.beans.os.GetReceiveBuffersHealth   cmdBean =
         new com.novell.web.command.beans.os.GetReceiveBuffersHealth();
   
try {
cmdBean.perform();
%>
<p>Receive Buffers Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Server Processes

<%
com.novell.web.command.beans.os.GetServerProcessesHealth   cmdBean =
         new com.novell.web.command.beans.os.GetServerProcessesHealth();
   
try {
cmdBean.perform();
%>
<p>Server Processes Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Get the Health of the Threads

<%
com.novell.web.command.beans.os.GetThreadsHealth   cmdBean =
            new com.novell.web.command.beans.os.GetThreadsHealth();
   
try {
cmdBean.perform();
%>
<p>Threads Health: <%=cmdBean.getHealth%></p>
<%
} catch(com.novell.web.command.CommandException e) {
%>
<p>CommandException: <%=e.toString()%></p>
<%
}
%>

Other Types of Information

The OS Command Beans included in Novell's MVC Beans for eBusiness provide many other Java Beans that allow access to other types of useful information, including:

  • General Server Information

  • Address Spaces Information

  • DMA Hardware Resource Information

  • DOS Drive Information

  • Hardware Interrupt Information

  • LAN Adapter Information

  • OS Module (NLM) Information

  • OS Resource Information

  • Processor Information

  • Server Screens Information

  • Slot Information

  • Port Information

  • Storage Adapters Information

  • Threads Information

  • Server Parameters Information

  • Namespace Provider Information

Customizing the View for Different Devices

Since we have used the new-paragraph tag to separate elements in our examples, we have made our examples transportable across HTML and WMl. Now, the only items we need to worry about are HDML element separators and the header and footer elements for each of these languages.

The following code snippets can be used to detect client device types, and to format element separators and header and footer information for these devices.

// DETECT CLIENT DEVICE
   //
   String deviceLang = "";
   // Check whether the browser/gateway accepts WML
   String acceptHeader = request.getHeader("Accept");
   if (acceptHeader.toUpperCase().indexOf("VND.WAP.WML") >= 0) {
      deviceLang = "WML"; 
   } else if (acceptHeader.toUpperCase().indexOf("APPLICATION/X-HDMLC") >= 0)  {
      deviceLang = "HDML";
   } else if (acceptHeader.toUpperCase().indexOf("TEXT/X-HDML") >= 0)  {
      deviceLang = "HDML";
   } else {
      // Now check for specific browsers
      String acceptHeader = request.getHeader("User-Agent");
      String browser = acceptHeader.substring(0, 4);
      if (browser.equals("Noki") || // Nokia phones and emulators 
         browser.equals("Eric") || // Ericsson WAP phones and emulators 
         browser.equals("WapI") || // Ericsson WapIDE 2.0 
         browser.equals("MC21") || // Ericsson MC218 
         browser.equals("AUR ") || // Ericsson R320 
         browser.equals("R380") || // Ericsson R380 
         browser.equals("UP.B") || // UP.Browser 
         browser.equals("WinW") || // WinWAP browser 
         browser.equals("UPG1") || // UP.SDK 4.0 
         browser.equals("upsi") || // another kind of UP.Browser 
         browser.equals("QWAP") || // unknown QWAPPER browser 
         browser.equals("Jigs") || // unknown JigSaw browser 
         browser.equals("Java") || // unknown Java based browser 
         browser.equals("Alca") || // unknown Alcatel-BE3 browser 
         browser.equals("MITS") || // unknown Mitsubishi browser 
         browser.equals("MOT-") || // unknown browser 
         browser.equals("My S") || // unknown Ericsson devkit browser
         browser.equals("WAPJ") || // Virtual WAPJAG www.wapjag.de 
         browser.equals("fetc") || // www.wapcab.de Perl script 
         browser.equals("ALAV") || // another unknown UP based browser 
         browser.equals("Wapa")) { // another unknown browser
         deviceLang = "WML"; 
      } else { 
         deviceLang = "HTML";
      }
   }
   
   // restrict page caching
   //
   response.setHeader("Cache-Control", "no-store"); 
   response.setHeader("Pragma", "no-cache"); 
   response.setDateHeader ("Expires", 0);
   
   String separatorStart = "<p>";
   String separatorEnd = "</p>";
   
   
   
   
   
   
   
   
   
   // Write header information for specific language
   //
   if (deviceLang.equalsIgnoreCase("WML")) {
      response.setContentType("text/vnd.wap.wml");
      out.println("<?xml version=\"1.0\"?>");
      out.println("<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"");
      out.println("\"http://www.wapforum.org/DTD/wml_1.1.xml">");
      out.println("<wml>");
      out.println("<card id=\"FirstCard\" title=\"My Example Card\">");
   } else if (deviceLang.equalsIgnoreCase("HDML")) {
      response.setContentType("text/x-hdml");
      out.println("<HDML VERSION=\"3.0\">");
      out.println("<DISPLAY>");
      separatorStart = "";
      separatorEnd = "";
   } else {
      response.setContentType("text/html");
   }
   
   // Now, try an example with dynamic element separators
   //
   
   <%
   com.novell.web.command.beans.os.GetCacheHealth   cmdBean =
            new com.novell.web.command.beans.os.GetCacheHealth();
try {
cmdBean.perform();
   %>
<%=separatorStart%>Cache Health: <%=cmdBean.getHealth()%><%=separatorEnd%>
   <%
} catch(com.novell.web.command.CommandException e) {
   %>
<%=separatorStart%>CommandException: <%=e.toString()%><%=separatorEnd%>
   <%
}
   %>
   
   // Now, write footer information for specific language
   //
   if (deviceLang.equalsIgnoreCase("WML")) {
      out.println("</card>");
      out.println("</wml>");
   } else if (deviceLang.equalsIgnoreCase("HDML")) {
      out.println("</DISPLAY>");
      out.println("</HDML>");
   }

Summary

Server administration is becoming an overwhelming task for IS&T staffs. Using the model/view/controller pattern and the command beans provided by Novell's MVC Beans for eBusiness, we can provide network administators with powerful tools that are easy to use and customize for their company's needs. This enables network administrators to become more efficient at their jobs, save their company money, and develop an architecture that is easily adapted for future enhancements and requirements.

Additional References

The following links provide more information on the subject:

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates