Last Updated: June 25, 2006
STAF's Java support is provided in the JSTAF.jar file (located in either C:\STAF\bin\JSTAF.jar (by default) on Windows systems or /usr/local/staf/lib/JSTAF.jar (by default) on Unix systems. The STAF install adds the JSTAF.jar file to the CLASSPATH environment variable.
STAF externalizes the following primary classes to Java applications. These classes are:
These classes all reside in the com.ibm.staf package. In order to use them in a Java application, you must import the STAF package like so
import com.ibm.staf.*;
STAF externalizes two wrapper classes. These classes are
These classes all reside in the com.ibm.staf.wrapper package. In order to use them in a Java application, you must import the STAF wrapper package like so
import com.ibm.staf.wrapper.*;
The STAFHandle class is used to register, unregister, and submit service requests to STAF. Each Java application should create one and only one STAFHandle object. The act of creating this object registers the Java application with STAF using the name passed to the constructor. Once this is done, service requests may be submitted by one of two methods:
Before the Java application exits, it should unregister with STAF by calling the unRegister() method.
STAFHandle also defines the following constants which can be used as the syncOption parameter for the submit() and submit2() methods:
package com.ibm.staf; public class STAFHandle { public static final int ReqSync = 0; public static final int ReqFireAndForget = 1; public static final int ReqQueue = 2; public static final int ReqRetain = 3; public static final int ReqQueueRetain = 4; public STAFHandle(String handleName) throws STAFException; public STAFHandle(int staticHandleNumber) public String submit(String where, String service, String request) throws STAFException; public String submit(int syncOption, String where, String service, String request) throws STAFException; public STAFResult submit2(String where, String service, String request); public STAFResult submit2(int syncOption, String where, String service, String request); public void unRegister() throws STAFException; public int getHandle(); }
import com.ibm.staf.*; public class STAFTest { public static void main(String argv[]) { try { STAFHandle handle = new STAFHandle("MyApplication"); try { System.out.println("My handle is: " + handle.getHandle()); String result1 = handle.submit( "LOCAL", "PING", "PING"); System.out.println("PING Result: " + result1); String result2 = handle.submit( STAFHandle.ReqQueueRetain, "LOCAL", "PING", "PING"); System.out.println("PING Request number: " + result2); STAFResult result3 = handle.submit2( "LOCAL", "ECHO", "ECHO Hello"); System.out.println("ECHO Result: " + result3.result); STAFResult result4 = handle.submit2( STAFHandle.ReqRetain, "LOCAL", "ECHO", "ECHO Hello"); System.out.println( "Asynchronous ECHO Request number: " + result4.result); STAFResult result = handle.submit2( "local", "handle", "create handle name " + "MyStaticHandleName"); STAFHandle staticHandle; if (result.rc == 0) { staticHandle = new STAFHandle( new Integer(result.result).intValue()); } } catch (STAFException e) { System.out.println( "Error submitting request to STAF, RC: " + e.rc); System.out.println(e.getMessage()); } finally { handle.unRegister(); } } catch (STAFException e) { System.out.println( "Error (un)registering with STAF, RC:" + e.rc); System.exit(1); } } // End of main() } // End of STAFTest
The STAFException class is the exception class thrown by the STAFHandle class. It contains an rc variable which contains the actual return code from STAF. You may use the standard Throwable method getMessage() to retrieve any extra information provided by STAF.
package com.ibm.staf; public class STAFException extends Exception { public STAFException(); public STAFException(int theRC); public STAFException(int theRC, String s); public int rc; }
import com.ibm.staf.*; try { STAFHandle handle = new STAFHandle("MyApplication"); System.out.println("My handle is: " + handle.getHandle()); } catch (STAFException e) { System.out.println("Error registering with STAF, RC:" + e.rc); System.exit(1); }
The STAFResult class is returned by the STAFHandle.submit2() method. It contains both the STAF return code as well as the result string. It is typically used in places where you wish to avoid catching exceptions when using STAF. This class also contains the constant definitions for all the STAF return codes. These return codes are common to STAFResult and STAFException.
package com.ibm.staf; public class STAFResult { STAFResult(); STAFResult(int theRC); STAFResult(int theRC, String theResult); public int rc; public String result; public static final int Ok = 0; public static final int InvalidAPI = 1; public static final int UnknownService = 2; public static final int InvalidHandle = 3; public static final int HandleAlreadyExists = 4; public static final int HandleDoesNotExist = 5; public static final int UnknownError = 6; public static final int InvalidRequestString = 7; public static final int InvalidServiceResult = 8; public static final int REXXError = 9; public static final int BaseOSError = 10; public static final int ProcessAlreadyComplete = 11; public static final int ProcessNotComplete = 12; public static final int VariableDoesNotExist = 13; public static final int UnResolvableString = 14; public static final int InvalidResolveString = 15; public static final int NoPathToMachine = 16; public static final int FileOpenError = 17; public static final int FileReadError = 18; public static final int FileWriteError = 19; public static final int FileDeleteError = 20; public static final int STAFNotRunning = 21; public static final int CommunicationError = 22; public static final int TrusteeDoesNotExist = 23; public static final int InvalidTrustLevel = 24; public static final int AccessDenied = 25; public static final int STAFRegistrationError = 26; public static final int ServiceConfigurationError = 27; public static final int QueueFull = 28; public static final int NoQueueElement = 29; public static final int NotifieeDoesNotExist = 30; public static final int InvalidAPILevel = 31; public static final int ServiceNotUnregisterable = 32; public static final int ServiceNotAvailable = 33; public static final int SemaphoreDoesNotExist = 34; public static final int NotSemaphoreOwner = 35; public static final int SemaphoreHasPendingRequests = 36; public static final int Timeout = 37; public static final int JavaError = 38; public static final int ConverterError = 39; public static final int NotUsed = 40; public static final int InvalidObject = 41; public static final int InvalidParm = 42; public static final int RequestNumberNotFound = 43; public static final int InvalidAsynchOption = 44; public static final int RequestNotComplete = 45; public static final int ProcessAuthenticationDenied = 46; public static final int InvalidValue = 47; public static final int DoesNotExist = 48; public static final int AlreadyExists = 49; public static final int DirectoryNotEmpty = 50; public static final int DirectoryCopyError = 51; public static final int DiagnosticsNotEnabled = 52; public static final int HandleAuthenticationDenied = 53; public static final int HandleAlreadyAuthenticated = 54; public static final int InvalidSTAFVersion = 55; public static final int RequestCancelled = 56; public static final int UserDefined = 4000; }
import com.ibm.staf.*; // The variable "handle" is an instance of the STAFHandle class that was // previously instantiated. STAFResult result = handle.submit2("local", "PING", "PING"); if (result.rc == STAFResult.Ok) { System.out.println("Successful PING request. " + "Result=" + result.result); } else { System.out.println("Error submitting PING request. " + "RC: " + result.rc + " Result: " + result.result); }
The STAFMapClassDefinition class provides the metadata associated with a map class. In particular, it defines the keys associated with the map class. This class is used to create and/or access a STAF map class definition which can be useful if you want to generate a STAF marshalling context with map classes. The map class definition is used to reduce the size of a marshalling map class in comparison to a map containing the same data. It also contains information about how to display instances of the map class, such as the order in which to display the keys and the display names to use for the keys. You get and set map class definitions using the STAFMarshallingContext class setMapClassDefinition and getMapClassDefinition functions.
When constructing a new STAFMapClassDefinition object, the required argument name specifies the name of the STAF map class definition.
STAFMapClassDefinition defines the following methods:
The required argument keyName specifies the name of a key.
The optional argument displayName specifies a string to use when displaying the key. The default is null which indicates to use the actual key name when displaying the key.
The required argument keyName specifies the name of a key for which this property is being set.
The required argument property specifies the name of the property being set. The only property name currently recognized 'display-short-name' which is used by the STAF executable when displaying a result in a tabular format when the length of the values for the fields is less than the length of the 'display-name'.
The required argument value specifies the value for the property being set.
package com.ibm.staf; public class STAFMapClassDefinition { public STAFMapClassDefinition(String name); public Map createInstance(); public void addKey(String keyName); public void addKey(String keyName, String displayName); public void setKeyProperty(String keyName, String property, String value); public Iterator keyIterator(); public String name(); }
import com.ibm.staf.*; import java.util.*; public class TestMarshalling { public static void main(String [] argv) { // Define a map class for querying information about a test myMapClass = new STAFMapClassDefinition("MyApp/Test/MyMap"); myMapClass.addKey("name", "Name"); myMapClass.addKey("exec", "Executable"); myMapClass.addKey("testType", "Test Type"); myMapClass.setKeyProperty("testType", "display-short-name", "Type"); // Create a marshalling context and assign a map class definition to it STAFMarshallingContext mc = new STAFMarshallingContext(); mc.setMapClassDefinition(myMapClass); // Create an instance of this map class definition and assign data // to the map class instance Map testMap = myMapClass.createInstance(); testMap.put("name", "TestA"); testMap.put("exec", "C:/tests/TestA.exe"); testMap.put("testType", "FVT"); // Set the map as the root object for the marshalling context mc.setRootObject(testMap); // Print the marshalling context in a human-readable format System.out.println("Formatted output:\n" + mc.toString()); // Create a marshalled string String result = mc.marshall(); } private static STAFMapClassDefinition myMapClass; }
Formatted output: { Name : TestA Executable: C:/tests/TestA.exe Test Type : FVT }
The STAFMarshallingContext class is used to create and/or access a STAF marshalling context which is used by STAF to help in marshalling and unmarshalling data. A marshalling context is simply a container for map class definitions and a data structure that uses (or is defined in terms of) them.
In order to use a map class when marshalling data, you must add the map class definition to the marshalling context, set the root object of the marshalling context to the object you want to marshall, and then marshall the marshalling context itself. When you unmarshall a data structure, you will always receive a marshalling context. Any map class definitions referenced by map classes within the data structure will be present in the marshalling context.
The primary use of this class is to represent multi-valued results that consist of a data structure (e.g. results from a QUERY/LIST service request, etc.) as a string that can also be converted back into the data structure. This string can be assigned to the string result buffer returned from the service request.
When constructing a new STAFMarshalling class object, the optional argument obj specifies the root object to be marshalled. The default is null.
STAFMarshallingContext defines the following methods:
The required argument mapClassDef specifies a STAFMapClassDefinition object that can be used when marshalling the object. You may call this method any number of times to set multiple STAFMapClassDefinition objects for the marshalling context.
The required argument mapClassName specifies a String containing the name of the MapClassDefinition object that you want to return.
The required argument mapClassName specifies a String containing the name of the MapClassDefinition object that you want to check if the marshalling context's contains in its list of map class defintions.
The required argument rootObject can specify any Object.
The STAFMarshallingContex class defines following static methods
More information on these static methods are provided later in this section.
package com.ibm.staf; public class STAFMarshallingContext { public static final int UNMARSHALLING_DEFAULTS = 0; public static final int IGNORE_INDIRECT_OBJECTS = 1; public static boolean isMarshalledData(String someData); public STAFMarshallingContext(); public STAFMarshallingContext(Object obj); public void setMapClassDefinition(STAFMapClassDefinition mapClassDef); public STAFMapClassDefinition getMapClassDefinition(String mapClassName); public boolean hasMapClassDefinition(String mapClassName); public Iterator mapClassDefinitionIterator(); public void setRootObject(Object rootObject); public Object getRootObject(); public Object getPrimaryObject(); public String marshall(); public static String marshall(Object object, STAFMarshallingContext context); public static STAFMarshallingContext unmarshall(String marshalledObject); public static STAFMarshallingContext unmarshall( String marshalledObject, int flags); public static STAFMarshallingContext unmarshall( String data, STAFMarshallingContext context); public static STAFMarshallingContext unmarshall( String data, STAFMarshallingContext context, int flags); public static String formatObject(Object obj); public String toString(); }
import com.ibm.staf.*; import java.util.*; public class TestMarshalling { public static void main(String [] argv) { // Define a map class for querying information about a test myMapClass = new STAFMapClassDefinition("MyApp/Test/MyMap"); myMapClass.addKey("name", "Name"); myMapClass.addKey("exec", "Executable"); myMapClass.addKey("testType", "Test Type"); myMapClass.setKeyProperty("testType", "display-short-name", "Type"); // Create a marshalling context and assign a map class definition to it STAFMarshallingContext mc = new STAFMarshallingContext(); mc.setMapClassDefinition(myMapClass); // Create an instance of this map class definition and assign data // to the map class instance Map testMap = myMapClass.createInstance(); testMap.put("name", "TestA"); testMap.put("exec", "C:/tests/TestA.exe"); testMap.put("testType", "FVT"); // Set the map as the root object for the marshalling context mc.setRootObject(testMap); // Print the marshalling context in a human-readable format System.out.println("Formatted output:\n" + mc.toString()); // Create a marshalled string String result = mc.marshall(); } private static STAFMapClassDefinition myMapClass; }
Formatted output: { Name : TestA Executable: C:/tests/TestA.exe Test Type : FVT }
The required argument someData is a String.
if (STAFMarshallingContext.isMarshalledData(result.result)) { STAFMarshallingContext mc = STAFMarshallingContext.unmarshall( result.result); }
The required argument object can be any Object.
The required argument context specifies the STAFMarshallingContext object that should be used when creating the marshalled string. You can specify null if you don't need to specify a marshalling context.
import com.ibm.staf.*; import java.util.*; public class MarshallTest3 { public static void main(String [] argv) { Map myMap = new HashMap(); myMap.put("name", "TestA"); myMap.put("exec", "C:/tests/TestA.exe"); myMap.put("testType", "FVT"); // Create a marshalled string (without a marshalling context) String result = STAFMarshallingContext.marshall(myMap, null); // Unmarshall the string and print it in a nicely formatted way STAFMarshallingContext mc = STAFMarshallingContext.unmarshall(result); System.out.println(mc); // Note: If you have a marshalling context object, then // just use the non-static marshall() method instead. String result2 = mc.marshall(); } }
{ exec : C:/tests/TestA.exe name : TestA testType: FVT }
The required argument marshalledObject is a string to be unmarshalled.
The required argument marshalledObject is a string to be unmarshalled.
The required argument flags can be used to control how to unmarshall the string. When a string is unmarshalled into a data structure, it is possible that one of the string objects that is unmarshalled is itself the string form of another marshalled data structure. Use STAFMarshallingContext.UNMARSHALLING_DEFAULTS to recursively unmarshall these nested objects. Use STAFMarshallingContext.IGNORE_INDIRECT_OBJECTS to disable this additional processing.
The required argument marshalledObject is a string to be unmarshalled.
The required argument context specifies the STAFMarshallingContext object that should be used when generating when unmarshalling the string. You can specify null for this argument.
The required argument marshalledObject is a string to be unmarshalled.
The required argument context specifies the STAFMarshallingContext object that should be used when generating when unmarshalling the string. You can specify null for this argument.
The required argument flags can be used to control how to unmarshall the string. When a string is unmarshalled into a data structure, it is possible that one of the string objects that is unmarshalled is itself the string form of another marshalled data structure. Use STAMarshallingContext.UNMARSHALLING_DEFAULTS to recursively unmarshall these nested objects. Use STAFMarshalingContext.IGNORE_INDIRECT_OBJECTS to disable this additional processing.
Here is the STAF request that this example executes and its result as shown when run using the STAF executable which "pretty prints" the result.
C:\>STAF local FS LIST DIRECTORY {STAF/Config/STAFRoot} Response -------- lib codepage STAFInst samples include bin docs data services STAFReg.inf LICENSE.htm
import com.ibm.staf.*; import java.util.*; public class TestUnmarshallList { public static void main(String [] argv) { // Register with STAF try { handle = new STAFHandle("MyApp/Test"); } catch (STAFException e) { System.out.println( "Error registering with STAF, RC: " + e.rc); System.exit(1); } // Submit a request to the FS service to LIST the contents of // the STAF root directory String machine = "local"; String service = "FS"; String request = "LIST DIRECTORY {STAF/Config/STAFRoot}"; STAFResult result = handle.submit2(machine, service, request); if (result.rc != STAFResult.Ok) { System.out.println( "Error submitting request STAF " + machine + " " + service + " " + request + "\nRC: " + result.rc + " Result: " + result.result); System.exit(1); } // The result from the request is a marshalled list of strings. // Unmarshall the result. STAFMarshallingContext mc = STAFMarshallingContext.unmarshall(result.result); List entryList = (List)mc.getRootObject(); // Check if an entry named "bin" is in the directory list Iterator iter = entryList.iterator(); while (iter.hasNext()) { String entryName = (String)iter.next(); if (entryName.equals("bin")) { System.out.println( "The STAF root directory contains a directory " + "named bin"); } } } private static STAFHandle handle; }
The STAF root directory contains a directory named bin
Here is the STAF request that this example executes and its result as shown when run using the STAF executable which "pretty prints" the result.
Response -------- { Return Code: 0 Key :Files : [ { Return Code: 0 Data : LICENSE.htm STAFReg.inf codepage docs lib services STAFInst bin data include samples } ] }
import com.ibm.staf.*; import java.util.*; public class TestUnmarshallMap { public static void main(String [] argv) { // Register with STAF try { handle = new STAFHandle("MyApp/Test"); } catch (STAFException e) { System.out.println( "Error registering with STAF, RC: " + e.rc); System.exit(1); } // Submit a request to the PROCESS service to run a command that // lists the contents of the STAF root directory and waits for // the request to complete String machine = "local"; String service = "PROCESS"; String command = "dir {STAF/Config/STAFRoot}"; String request = "START COMMAND " + STAFUtil.wrapData(command) + " RETURNSTDOUT STDERRTOSTDOUT WAIT"; System.out.println( "STAF " + machine + " " + service + " " + request); STAFResult result = handle.submit2(machine, service, request); if (result.rc != STAFResult.Ok) { System.out.println( "Error submitting request STAF " + machine + " " + service + " " + request + "\nRC: " + result.rc + " Result: " + result.result); System.exit(1); } // Unmarshall the result buffer whose root object is a map // containing process completion information. The keys for this // map include 'rc' and 'fileList'. The value for 'fileList' // is a list of the returned files. Each entry in the list // consists of a map that contains keys 'rc' and 'data'. // In our PROCESS START request, we returned one file, STDOUT, // (and returned STDERR to the STDOUT file). STAFMarshallingContext mc = STAFMarshallingContext.unmarshall(result.result); Map processCompletionMap = (Map)mc.getRootObject(); // Verify that the process rc is 0 String processRC = (String)processCompletionMap.get("rc"); if (!processRC.equals("0")) { System.out.println( "ERROR: Process RC is " + processRC + " instead of 0."); System.exit(1); } // Verify that the rc is 0 for returning data to the STDOUT file List returnedFileList = (List)processCompletionMap.get( "fileList"); Map stdoutMap = (Map)returnedFileList.get(0); String stdoutRC = (String)stdoutMap.get("rc"); if (!stdoutRC.equals("0")) { System.out.println( "ERROR retrieving process Stdout data. RC=" + stdoutRC); System.exit(1); } // Get the data from the STDOUT file created by the process // and print it String stdoutData = (String)stdoutMap.get("data"); System.out.println("\nProcess Stdout File Contains:\n"); System.out.println(stdoutData); } private static STAFHandle handle; }
STAF local PROCESS START COMMAND :26:dir {STAF/Config/STAFRoot} RETURNSTDOUT STDERRTOSTDOUT WAIT
Process Stdout File Contains: LICENSE.htm STAFReg.inf codepage docs lib services STAFInst bin data include samples
The required argument obj specifies any Object to be formatted in a verbose, more readable format.
String request = "QUERY ENTRY {STAF/Config/ConfigFile}"; STAFResult result = handle.submit2("local", "FS", request); if (result.rc != STAFResult.Ok) { System.out.println( "Error submitting request STAF local FS " + request + "\nRC: " + result.rc + " Result: " + result.result); System.exit(1); } STAFMarshallingContext mc = STAFMarshallingContext.unmarshall(result.result); System.out.println( "Formatted output using formatObject():\n" + STAFMarshallingContext.formatObject(mc)); // Note: Instead of using the static formatObject method, if you // have a STAFMarshallingContext object (e.g. mc), you can simply // print the marshalling context object itself to get the same // output because the toString() function for a STAFMarshallingContext // object calls the formatObject function. System.out.println("\nFormatted output using toString():\n" + mc);
Formatted output using formatObject(): { Name : C:\STAF\bin\staf.cfg Type : F Upper 32-bit Size : 0 Lower 32-bit Size : 6612 Modified Date-Time: 20050506-16:08:08 } Formatted output using toString(): { Name : C:\STAF\bin\staf.cfg Type : F Upper 32-bit Size : 0 Lower 32-bit Size : 6612 Modified Date-Time: 20050506-16:08:08 }
The STAFQueueMessage class provides a wrapper around messages received via the STAF Queue service. It takes the received string as input and unmarshalls it and breaks it into its constituent parts.
package com.ibm.staf; public class STAFQueueMessage { public STAFQueueMessage(String queueMessage); public int priority; public String timestamp; public String machine; public String handleName; public int handle; public String type; public Object message; public STAFMarshallingContext mc; }
import com.ibm.staf.*; public class TestQueue { // This is the main command line entry point public static void main(String [] argv) { // Verify the command line arguments if (argv.length != 0) { System.out.println(); System.out.println("Usage: java TestQueue"); System.exit(1); } // Register with STAF try { handle = new STAFHandle("Queue_Class_Test"); } catch (STAFException e) { System.out.println("Error registering with STAF, RC: " + e.rc); System.exit(1); } System.out.println("Please send a queue message to handle " + handle.getHandle() + " now"); STAFResult queueResult = handle.submit2("local", "queue", "get wait"); if (queueResult.rc != 0) { System.out.println("Error getting message from queue, RC: " + queueResult.rc + ", Additional Info: " + queueResult.result); System.exit(1); } STAFQueueMessage message = new STAFQueueMessage(queueResult.result); System.out.println("Priority : " + message.priority); System.out.println("Timestamp : " + message.timestamp); System.out.println("Machine : " + message.machine); System.out.println("Handle name: " + message.handleName); System.out.println("Handle : " + message.handle); System.out.println("Type : " + message.type); System.out.println("Message : " + message.message); } private static STAFHandle handle; }
C:\>staf local queue queue handle 71 message "Hi there" type "MyType" Response --------
C:\>java TestQueue Please send a queue message to handle 71 now Priority : 5 Timestamp : 20050516-12:31:42 Machine : local://local Handle name: STAF/Client Handle : 73 Type : MyType Message : Hi there C:>
The STAFUtil class contains the following static functions that are general utility functions:
The required argument data is a string.
For example, if the data is Hello world, this method would return a string containing :11:Hello world.
public class STAFUtil { public static String wrapData(String data); }
// Submit a request to the LOG service to log a message String message = "Hello world"; STAFResult result = handle.submit2( "local", "LOG", "LOG GLOBAL LOGNAME MyLog " + "MESSAGE " + STAFUtil.wrapData(message) + " LEVEL Info"); // Submit a request to the PROCESS service to run a command that // lists the contents of the STAF root directory and waits for // the request to complete String machine = "local"; String service = "PROCESS"; String command = "dir {STAF/Config/STAFRoot}"; String request = "START COMMAND " + STAFUtil.wrapData(command) + " RETURNSTDOUT STDERRTOSTDOUT WAIT"; STAFResult result = handle.submit2(machine, service, request);
The required argument data is a string.
For example, if the data is :8:Hi there, this method would return a string containing Hi there.
public class STAFUtil { public static String unwrapData(String data); }
String wrappedMessage = STAFUtil.wrapData("Hello world"); String unwrappedMessage = STAFUtil.unwrapData(wrappedMessage);
The required argument endpoint is a string.
For example, if the endpoint specified is tcp://client1.company.com@6500, it would return tcp://client1.company.com.
public class STAFUtil { public static String stripPortFromEndpoint(String endpoint); }
String endpoint = STAFUtil.stripPortFromEndpoint( "tcp://client1.company.com@6500");
Required parameter requiredTrustLevel specifies the required trust level for this service request.
Required parameter service specifies the registered name of the service.
Required parameter request specifies the first word (or two) to uniquely identify the request if an error occurs.
Required parameter localMachine specifies the logical identifier for the service machine which will be used in the error message if the requesting machine has insufficient trust.
Required parameter info specified the request information.
This method returns a STAFResult object. If successful, the return code (rc) in the STAFResult object will be STAFResult.Ok and the result buffer (result) in the STAFResult object will be blank. If not successful, a non-zero return code will set and the result buffer will contain a detailed error message.
public class STAFUtil { public static STAFResult validateTrust( int requiredTrustLevel, String service, String request, String localMachine, STAFServiceInterfaceLevel30.RequestInfo info); }
Required argument value is a String that may contain STAF variables to be resolved (e.g. "{STAF/Config/Machine}").
Required argument handle is a STAFHandle object.
Requires argument requestNumber is the request number.
Returns a STAFResult object. If successful, the rc (return code) in the STAFResult object will be set to STAFResult.Ok and the result (result buffer) in the STAFResult object will contain a string with all STAF variables resolved. If unsuccessful, the rc will be set to a non-zero integer and the result string will contain an error message.
public class STAFUtil { public static STAFResult resolveRequestVar( String value, STAFHandle handle, int requestNumber); }
Required argument option is a String that contains the name of an option in a service request whose value is being resolved.
Required argument value is a String that may contain STAF variables to be resolved (e.g. "{STAF/Config/Machine}").
Required argument handle is a STAFHandle object.
Requires argument requestNumber is the request number.
Returns a STAFResult object. If successful, the rc (return code) in the STAFResult object will be set to STAFResult.Ok and the result (result buffer) in the STAFResult object will contain a string with all STAF variables resolved. If unsuccessful, the rc will be set to a non-zero integer and the result string will contain an error message.
public class STAFUtil { public static STAFResult resolveRequestVarAndCheckInt( String option, String value, STAFHandle handle, int requestNumber); }
Required argument value is a String that may contain STAF variables to be resolved (e.g. "STAF/Config/Machine}").
Required argument handle is a STAFHandle object.
Returns a STAFResult object. If successful, the rc (return code) in the STAFResult object will be set to STAFResult.Ok and the result (result buffer) in the STAFResult object will contain a string with all STAF variables resolved. If unsuccessful, the rc will be set to a non-zero integer and the result string will contain an error message.
public class STAFUtil { public static STAFResult resolveInitVar(String value, STAFHandle handle); }
Required argument option is a String that contains the name of an option in a service request whose value is being resolved.
Required argument value is a String that may contain STAF variables to be resolved (e.g. "STAF/Config/Machine}").
Required argument handle is a STAFHandle object.
Returns a STAFResult object. If successful, the rc (return code) in the STAFResult object will be set to STAFResult.Ok and the result (result buffer) in the STAFResult object will contain a string with all STAF variables resolved. If unsuccessful, the rc will be set to a non-zero integer and the result string will contain an error message.
public class STAFUtil { public static STAFResult resolveInitVarAndCheckInt( String option, String value, STAFHandle handle); }
Required argument machine is a String that contains the endpoint of the machine whose STAF or STAF service version is to be compared.
Required argument handle is a STAFHandle object used to submit the request.
Required argument minRequiredVersion is a String that
contains the minimum version required on the machine.
The version must have the following format unless it's blank or
"
Optional argument service is a String that
contains the name of the service for which you want to compare its
version. Defaults to MISC which means that you want to compare
the version of STAF running. Or, you can specify the name of a
STAF service (such as STAX, Event, Cron, etc.) that implements a
VERSION request.
STAF Versions are compared as follows:
Examples:
Returns a STAFResult object. If successful (the version is at or
above the required version), the rc (return code) in the STAFResult
object will be set to STAFResult.Ok and the result (result buffer) in
the STAFResult object will contain the version of STAF (or of the
specified STAF service) running on the specified machine.
If unsuccessful, the rc will be set to a non-zero integer and the
result string will contain an error message.
If the version is lower than the mininum required version,
STAFResult.InvalidSTAFVersion is returned in the rc with an error
message returned in the result. If another error occurs (e.g. RC 16
if the machine is not currently running STAF, etc.), an error message
will be returned in the result.
Since: STAF V3.1.0
a[.b[.c[.d]]] [text]
where:
"3" = "3.0" = "3.0.0" = 3.0.0.0"
"3.0.0" < "3.1.0"
"3.0.2" < "3.0.3"
"3.0.9" < "3.0.10"
"3.0.0" < "3.1"
"3.1.0 Alpha 1" < "3.1.0 Beta 1"
"3.1.0 Beta 1" < "3.1.0"
public class STAFUtil { public static STAFResult compareSTAFVersion( String machine, STAFHandle handle, String minRequiredVersion); }
public class MyService implements STAFServiceInterfaceLevel30 { // Version of STAF (or later) required for this service private final String kRequiredSTAFVersion = "3.1.0"; private STAFHandle fHandle; public STAFResult init(STAFServiceInterfaceLevel30.InitInfo info) { try { fHandle = new STAFHandle("STAF/SERVICE/" + info.name); } catch (STAFException e) { return new STAFResult(STAFResult.STAFRegistrationError, e.toString()); } // Verify that the required version of STAF is running on the // local service machine. STAFResult res = new STAFResult(); try { res = STAFUtil.compareSTAFVersion( "local", fHandle, kRequiredSTAFVersion); } catch (Error err) { // Note: Method compareSTAFVersion was added in STAF V3.1.0 // so need to catch a NoSuchMethod error return new STAFResult( STAFResult.ServiceConfigurationError, "This service requires STAF Version " + kRequiredSTAFVersion + " or later."); } if (res.rc != STAFResult.Ok) { if (res.rc == STAFResult.InvalidSTAFVersion) { return new STAFResult( STAFResult.ServiceConfigurationError, "Minimum required STAF version for this service " + "is not running. " + res.result); } else { return new STAFResult( STAFResult.ServiceConfigurationError, "Error verifying the STAF version. RC: " + res.rc + ", Additional info: " + res.result); } } ... } ... }
// Assumes a STAF Handle called fHandle has already been created STAFResult res = new STAFResult(); String machine = "server1"; String service = "STAX"; String requiredVersion = "3.1"; try { res = STAFUtil.compareSTAFVersion( machine, fHandle, requiredVersion, service); } catch (Error err) { // The required version of STAF is not running as class STAFVersion // was added in STAF V3.1 so this catches a NoSuchMethod error ... } if (res.rc != STAFResult.Ok) { if (res.rc == STAFResult.InvalidSTAFVersion) { // Service version on the machine is lower than 3.1 ... } else { // Error occurred trying to verify the version of the STAX service // on the machine ... } }
This method should be used by anyone who wants to protect private data specified in a STAF command option that supports handling private data.
Required argument data is a String that contains data you want to protect.
Returns a String object containing the string with opening and closing privacy delimiters added and escapes any privacy delimiters already contained in the string with a caret (^). If the string has length 0 or already has an unescaped opening privacy delimiter at the beginning and an unescaped closing privacy delimiter at the end, privacy delimiters are not added.
Examples:
Since: STAF V3.1.0
public class STAFUtil { public static String addPrivacyDelimiters(String data); }
String password = STAFUtil.addPrivacyDelimiters("passw0rd"); String request = "START COMMAND C:/tests/TestA.exe USERNAME Test1" + " PASSWORD " + password; STAFResult result = handle.submit2("local", "PROCESS", request);
String command = "C:/tests/admin -password " + STAFUtil.addPrivacyDelimiters("secret"); String request = "START COMMAND " + STAFUtil.wrapData(command); STAFResult result = handle.submit2("local", "PROCESS", request);
This method should be used before calling the addPrivacyDelimiters method for data that needs to be protected but may contain substrings !!@ and/or @!! that should not be mistaken for privacy delimiters .
Required argument data is a String.
Returns a String object containing the updated data.
For example, if the data is "passw@!!d", this method would return "passw^@!!d".
Since: STAF V3.1.0
public class STAFUtil { public static String escapePrivacyDelimiters(String data); }
String password = STAFUtil.addPrivacyDelimiters( STAFUtil.escapePrivacyDelimiters("passw@!!d")); String request = "START COMMAND C:/tests/TestA.exe USERNAME Test1" + " PASSWORD " + password; STAFResult result = handle.submit2("local", "PROCESS", request);
Required argument data is a String that may contain privacy delimiters.
Optional argument numLevels in an int that specifies the number of levels of privacy data to remove. The default is 0 which indicates to remove all levels of privacy data. Note that, generally, you'll want to remove all levels of privacy delimiters.
Returns a String object containing the updated data with privacy delimiters removed.
Examples:
Since: STAF V3.1.0
public class STAFUtil { public static String removePrivacyDelimiters(String data); public static String removePrivacyDelimiters(String data, int numLevels); }
String protectedPassword = "!!@secret@!!"'; String password = STAFUtil.removePrivacyDelimiters(protectedPassword);
Required argument data is a String that may contain privacy delimiters.
Returns a String object containing the string with any private data masked.
Examples:
Since: STAF V3.1.0
public class STAFUtil { public static String maskPrivateData(String data); }
String request = "START COMMAND C:/tests/TestA.exe USERNAME Test1" + " PASSWORD " + STAFUtil.addPrivacyDelimiters("passw0rd"); System.out.println(STAFUtil.maskPrivateData(request);
The STAFVersion class allows you to compare STAF versions. This class is useful if you want to verify that a STAF version or a version of a STAF service is at a particular level of STAF.
package com.ibm.staf; public class STAFVersion { public static int NUM_VERSION_LEVELS = 4; public STAFVersion(String version) throws NumberFormatException; public int compareTo(STAFVersion version); public String getVersion(); public int[] getVersionArray(); public String getText(); public String toString(); }
When constructing a new STAFVersion object, the
required argument version is a string containing the STAF version.
A STAF version must be of the following format unless it's blank or
" A NumberFormatException is thrown if a non-numeric value is specified
in a, b, c, or d.
Since: STAF V3.1.0
STAFVersion defines the following methods:
The required argument version is a STAFVersion object
representing the STAF version to compare.
STAFVersion instances are compared as follows:
Examples:
This method returns an integer as follows:
The STAFLog class provides a wrapper around the LOG command of the LOG
service. It provides constants for the log type and log levels. It has
instance and static methods for logging. The STAFLog class also interfaces
with the MONITOR service. You may provide the STAFLog class a monitor mask.
For the levels set in the monitor mask, STAFLog will log the message via the
LOG service and then log the message via the MONITOR service. STAFLog will
also log an error message to the MONITOR service, if it should receive an
error while trying to log a message.
The STAFMonitor class provides a wrapper around the LOG command of the
MONITOR service. It has instance and static methods for logging messages to the
MONITOR service.
The STAFLogViewer class provides a Java GUI that can display any STAF log.
It can be accessed via the command line or via another Java program.
To execute and get help from the STAFLogViewer class from the command line,
specify the following:
The STAFLogViewer class accepts the following command line parameters:
-serviceName specifies the name of the log service. This parameter
is optional. The default is LOG.
-queryRequest specifies the log query options. This parameter is
required (unless you are specifying the -help or -version
parameters). It should begin with
the QUERY option and include any additional query options, including
the options to specify whether the log is a GLOBAL, MACHINE, or HANDLE log. You
may not specify the LEVELMASK option within the queryRequest.
To specify the LEVELMASK option, use the -levelMask
parameter.
-levelMask specifies the log levels to be initially displayed. This
parameter is optional. The default is to display all log levels.
Only level names are supported (for example
"ERROR DEBUG".); use of the 32 byte bit string to represent
the log mask is not supported. These are the log levels that will be displayed
when the initial STAFLogViewer is displayed. The user can then change the
log levels to be displayed via the "Levels" menu.
-fontName specifies the name of the font to use when displaying the
STAF log. This parameter is optional. The default is Courier.
Examples of other fonts are Dialog and TimesRoman.
-help displays help information for the STAFLogViewer.
This parameter is optional.
-version displays the version of the STAFLogViewer.
This parameter is optional.
You may also call the STAFLogViewer class from a Java application. The
following constructors for STAFLogViewer are provided:
Here is an example of the Java GUI that is displayed for the following
command:
The STAFLogViewer menu bar provides the following menus:
a[.b[.c[.d]]] [text]
where:
"3" = "3.0" = "3.0.0" = 3.0.0.0"
"3.0.0" < "3.1.0"
"3.0.2" < "3.0.3"
"3.0.0" < "3.1"
"3.0.9" < "3.0.10"
"3.1.0 Alpha 1" < "3.1.0 Beta 1"
"3.1.0 Beta 1" < "3.1.0"
Examples
Suppose you already had the STAF version that you wanted to compare
in a String variable named versionStr and you wanted to
make sure that it was at version 3.1.0 or higher. You could check
this as follows:
String reqVersionStr = "3.1";
try
{
STAFVersion version = new STAFVersion(versionStr);
STAFVersion requiredVersion = new STAFVersion(reqVersionStr);
if (version.compareTo(requiredVersion) < 0)
{
// Version is lower than the minimum required version
return new STAFResult(
STAFResult.InvalidSTAFVersion,
"Version is " + versionStr + ". Version " +
reqVersionStr + " or later is required.");
}
}
catch (NumberFormatException e)
{
return new STAFResult(
STAFResult.InvalidValue,
"Invalid value specified for version, Exception info: " +
e.toString());
}
catch (Error err)
{
// Note: Class STAFVersion was added in STAF V3.1.0
// so need to catch a NoSuchMethod error
return new STAFResult(
STAFResult.InvalidSTAFVersion,
"Version is " + versionStr + ". Version " +
reqVersionStr + " or later is required.");
}
3.9 Class STAFLog
Definition
package com.ibm.staf.wrapper;
public class STAFLog
{
// Log type constants
public static final String GLOBAL = "GLOBAL";
public static final String MACHINE = "MACHINE";
public static final String HANDLE = "HANDLE";
// Log level constants (int format)
public static final int Fatal = 0x00000001;
public static final int Error = 0x00000002;
public static final int Warning = 0x00000004;
public static final int Info = 0x00000008;
public static final int Trace = 0x00000010;
public static final int Trace2 = 0x00000020;
public static final int Trace3 = 0x00000040;
public static final int Debug = 0x00000080;
public static final int Debug2 = 0x00000100;
public static final int Debug3 = 0x00000200;
public static final int Start = 0x00000400;
public static final int Stop = 0x00000800;
public static final int Pass = 0x00001000;
public static final int Fail = 0x00002000;
public static final int Status = 0x00004000;
public static final int Reserved1 = 0x00008000;
public static final int Reserved2 = 0x00010000;
public static final int Reserved3 = 0x00020000;
public static final int Reserved4 = 0x00040000;
public static final int Reserved5 = 0x00080000;
public static final int Reserved6 = 0x00100000;
public static final int Reserved7 = 0x00200000;
public static final int Reserved8 = 0x00400000;
public static final int Reserved9 = 0x00800000;
public static final int User1 = 0x01000000;
public static final int User2 = 0x02000000;
public static final int User3 = 0x04000000;
public static final int User4 = 0x08000000;
public static final int User5 = 0x10000000;
public static final int User6 = 0x20000000;
public static final int User7 = 0x40000000;
public static final int User8 = 0x80000000;
// Log level constants (String format)
public static final String FatalStr = "FATAL";
public static final String ErrorStr = "ERROR";
public static final String WarningStr = "WARNING";
public static final String InfoStr = "INFO";
public static final String TraceStr = "TRACE";
public static final String Trace2Str = "TRACE2";
public static final String Trace3Str = "TRACE3";
public static final String DebugStr = "DEBUG";
public static final String Debug2Str = "DEBUG2";
public static final String Debug3Str = "DEBUG3";
public static final String StartStr = "START";
public static final String StopStr = "STOP";
public static final String PassStr = "PASS";
public static final String FailStr = "FAIL";
public static final String StatusStr = "STATUS";
public static final String Reserved1Str = "RESERVED1";
public static final String Reserved2Str = "RESERVED2";
public static final String Reserved3Str = "RESERVED3";
public static final String Reserved4Str = "RESERVED4";
public static final String Reserved5Str = "RESERVED5";
public static final String Reserved6Str = "RESERVED6";
public static final String Reserved7Str = "RESERVED7";
public static final String Reserved8Str = "RESERVED8";
public static final String Reserved9Str = "RESERVED9";
public static final String User1Str = "USER1";
public static final String User2Str = "USER2";
public static final String User3Str = "USER3";
public static final String User4Str = "USER4";
public static final String User5Str = "USER5";
public static final String User6Str = "USER6";
public static final String User7Str = "USER7";
public static final String User8Str = "USER8";
// Constructors - Default monitor mask is 0x00007C07. This causes messages
// with log levels Fatal, Error, Warning, Start, Stop, Pass,
// Fail, and Status to also be logged via the MONITOR
// service
public STAFLog(String logType, String logName, STAFHandle handle);
public STAFLog(String logType, String logName, STAFHandle handle, int mask)
// Methods to actually log a message with a given level
public STAFResult log(int level, String msg)
public STAFResult log(String level, String msg)
public static STAFResult log(STAFHandle theHandle, String logType,
String logName, int level, String msg)
public static STAFResult log(STAFHandle theHandle, String logType,
String logName, String level, String msg)
public static STAFResult log(STAFHandle theHandle, String logType,
String logName, int level, String msg,
int mask)
public static STAFResult log(STAFHandle theHandle, String logType,
String logName, String level, String msg,
int mask)
// Accessor methods
public String getName();
public String getLogType();
public int getMonitorMask();
}
Examples
import com.ibm.staf.*;
import com.ibm.staf.wrapper.*;
...
...
// Create a log object that only logs Fatal and Error messages.
// myHandle is a STAFHandle object that was created earlier.
STAFLog logger = new STAFLog(STAFLog.GLOBAL, "MyLog", myHandle,
STAFLog.Fatal | STAFLog.Error);
STAFResult result;
// Log an error via the instance and static methods
result = logger.log(STAFLog.Error, "Error during test");
result = STAFLog.log(myHandle, STAFLog.GLOBAL, "MyLog", STAFLog.Error,
"Error during test");
// Set a mask to log Fatal, Error, Warning and Info messages.
// Then log a warning via a static method.
int myMask = STAFLog.Fatal | STAFLog.Error | STAFLog.Warning | STAFLog.Info;
result = STAFLog.log(myHandle, STAFLog.GLOBAL, "MyLog", STAFLog.Warning,
"This is just a warning", myMask);
3.10 Class STAFMonitor
Definition
package com.ibm.staf.wrapper;
public class STAFMonitor
{
// Constructor
STAFMonitor(STAFHandle stafHandle);
// Methods to log data to the MONITOR service
public STAFResult log(String message);
public static STAFResult log(STAFHandle theHandle, String message);
}
Examples
import com.ibm.staf.*;
import com.ibm.staf.wrapper.*;
...
...
// Create a monitor object. myHandle is a STAFHandle object that was created
// earlier.
STAFMonitor monitor = new STAFMonitor(myHandle);
STAFResult result;
// Log a message to the MONITOR service via the instance and static methods
result = monitor.log("Beginning phase 1");
result = STAFMonitor.log(myHandle, "Beginning phase 2");
3.11 Class STAFLogViewer
java com.ibm.staf.STAFLogViewer -help
-machine
You must specify -queryRequest or -help or -version.
-machine specifies the name of the machine where the STAF log is located.
This parameter is optional. The default is local.
public STAFLogViewer(Component parent,
STAFHandle handle,
String queryRequest)
public STAFLogViewer(Component parent,
STAFHandle handle,
String machine,
String queryRequest
public STAFLogViewer(Component parent,
STAFHandle handle,
String machine,
String serviceName,
String queryRequest)
public STAFLogViewer(Component parent,
STAFHandle handle,
String machine,
String serviceName,
String queryRequest,
String levelMask)
public STAFLogViewer(Component parent,
STAFHandle handle,
String machine,
String serviceName,
String queryRequest,
String levelMask,
String fontName)
java com.ibm.staf.STAFLogViewer -machine staf1f.austin.ibm.com -queryRequest "QUERY machine {STAF/Config/MachineNickname} logname email"
Examples
java com.ibm.staf.STAFLogViewer -queryRequest "QUERY machine {STAF/Config/MachineNickname} logname eventmanager last 20"
String queryRequest = " QUERY MACHINE {STAF/Config/MachineNickname}" +
" LOGNAME cron CONTAINS " +
STAFUtil.wrapData("ID=5 ");
STAFLogViewer logViewer = new STAFLogViewer(this, // This is Swing component such as JFrame
myHandle, // This is a STAFHandle object
"local",
"LOG",
queryRequest,
"ERROR DEBUG",
"TimesRoman");
4.0 Java Samples
4.1 Java Sample 1
This Java sample program is a multi-threaded STAF PING test.
The syntax to run this program is:
C:\>java JPing
Usage: java JPing
For each thread specified by the "# Threads" parameter), this program submits
a PING request to the PING service to ping the machine specified by the
"Where" parameter, repeating the request the number of times
specified by the "# Loops per thread" parameter.
A status message is displayed each time a number of loops
have completed based on the "Display Modulus" parameter.
When complete, an average number of pings per seconds is printed.
/*****************************************************************************/
/* Software Testing Automation Framework (STAF) */
/* (C) Copyright IBM Corp. 2001 */
/* */
/* This software is licensed under the Common Public License (CPL) V1.0. */
/*****************************************************************************/
//===========================================================================
// JPing - A multi-threaded STAF PING test
//===========================================================================
// Accepts: Where to PING
// Optionally, the number of threads to use (default = 5)
// Optionally, the number of loops per thread (default = 10000)
// Optionally, the display modulus (default = 250)
//
// Returns: 0 , on success
// >0, if an error is encountered
//===========================================================================
// Date Who Comment
// ---------- ------------ ------------------------------------------
// 04/25/1998 C. Rankin File Created
//===========================================================================
import com.ibm.staf.*;
import java.util.Date;
import java.util.Calendar;
import java.text.DateFormat;
public class JPing implements Runnable
{
// Constructor
public JPing(int numLoops, int displayModulus, int myThreadNum)
{
loopCount = numLoops;
modulus = displayModulus;
threadNum = myThreadNum;
errors = 0;
}
// This is the main command line entry point
public static void main(String [] argv)
{
// Verify the command line arguments
if ((argv.length < 1) || (argv.length > 4))
{
System.out.println();
System.out.println("Usage: java JPing <Where> [# Threads] " +
"[# Loops per thread] [Display Modulus]");
System.out.println();
System.out.println("Defaults:");
System.out.println();
System.out.println(" # Threads = 5");
System.out.println(" # Loops per thread = 10000");
System.out.println(" Display Modulus = 250");
System.out.println();
System.out.println("Examples:");
System.out.println();
System.out.println("java JPing local");
System.out.println("java JPing SomeServer 3 1000 100");
System.exit(1);
}
// Register with STAF
try
{
handle = new STAFHandle("Java_Ping_Test");
}
catch (STAFException e)
{
System.out.println("Error registering with STAF, RC: " + e.rc);
System.exit(1);
}
// Initialize variables
timeFormatter = DateFormat.getTimeInstance(DateFormat.MEDIUM);
where = argv[0];
int numThreads = 5;
int numLoops = 10000;
int displayModulus = 250;
if (argv.length > 1) numThreads = Integer.parseInt(argv[1]);
if (argv.length > 2) numLoops = Integer.parseInt(argv[2]);
if (argv.length > 3) displayModulus = Integer.parseInt(argv[3]);
JPing [] pingers = new JPing[numThreads];
Thread [] threads = new Thread[numThreads];
System.out.println("(0)" + timeFormatter.format(new Date()) +
" - Started");
long startSecs = (new Date()).getTime();
// Start the threads
for(int i = 0; i < numThreads; ++i)
{
pingers[i] = new JPing(numLoops, displayModulus, i + 1);
threads[i] = new Thread(pingers[i]);
threads[i].start();
}
// Wait for all the threads to finish
for(int i = 0; i < numThreads; ++i)
{
try
{
threads[i].join();
}
catch (Exception e)
{
System.out.println("Exception: " + e);
System.out.println(e.getMessage());
}
}
// Output final pings/sec
long stopSecs = (new Date()).getTime();
System.out.println("(0)" + timeFormatter.format(new Date()) +
" - Ended");
System.out.println("Average: " + ((numLoops * numThreads * 1000) /
(stopSecs - startSecs)) + " pings/sec");
// Unregister with STAF
try
{
handle.unRegister();
}
catch (STAFException e)
{
System.out.println("Error unregistering with STAF, RC: " + e.rc);
System.exit(1);
}
}
// This is the method called when each thread starts
public void run()
{
for(int i = 1; i <= loopCount; ++i)
{
STAFResult result = handle.submit2(where, "PING", "PING");
// If we get a non-zero return code, or a response of something
// other than "PONG", display an error
if (result.rc != 0)
{
System.out.println("(" + threadNum + ")" +
timeFormatter.format(new Date()) +
" - Loop #" + i + ", Error #" +
++errors + ", RC: " + result.rc);
}
else if (result.result.compareTo("PONG") != 0)
{
System.out.println("(" + threadNum + ")" +
timeFormatter.format(new Date()) +
" - Loop #" + i + ", Error #" +
++errors + ", RESULT = " + result.result);
}
// If we are at our display modulus display a status message
if ((i % modulus) == 0)
{
System.out.println("(" + threadNum + ")" +
timeFormatter.format(new Date()) +
" - Ended Loop #" + i + ", Errors = " +
errors);
}
}
}
private static STAFHandle handle;
private static String where;
private static DateFormat timeFormatter;
private int loopCount;
private int modulus;
private int threadNum;
private int errors;
}
Sample results could be:
C:\>java JPing local
(0)4:20:49 PM - Started
(1)4:20:50 PM - Ended Loop #250, Errors = 0
(3)4:20:50 PM - Ended Loop #250, Errors = 0
(2)4:20:50 PM - Ended Loop #250, Errors = 0
(5)4:20:50 PM - Ended Loop #250, Errors = 0
(4)4:20:50 PM - Ended Loop #250, Errors = 0
(3)4:20:51 PM - Ended Loop #500, Errors = 0
(1)4:20:51 PM - Ended Loop #500, Errors = 0
(2)4:20:51 PM - Ended Loop #500, Errors = 0
(5)4:20:51 PM - Ended Loop #500, Errors = 0
(4)4:20:51 PM - Ended Loop #500, Errors = 0
(3)4:20:52 PM - Ended Loop #750, Errors = 0
(1)4:20:52 PM - Ended Loop #750, Errors = 0
(2)4:20:52 PM - Ended Loop #750, Errors = 0
(5)4:20:52 PM - Ended Loop #750, Errors = 0
(4)4:20:52 PM - Ended Loop #750, Errors = 0
...
(2)4:21:19 PM - Ended Loop #9500, Errors = 0
(1)4:21:19 PM - Ended Loop #9500, Errors = 0
(3)4:21:19 PM - Ended Loop #9500, Errors = 0
(4)4:21:20 PM - Ended Loop #9500, Errors = 0
(5)4:21:20 PM - Ended Loop #9500, Errors = 0
(2)4:21:20 PM - Ended Loop #9750, Errors = 0
(1)4:21:20 PM - Ended Loop #9750, Errors = 0
(3)4:21:20 PM - Ended Loop #9750, Errors = 0
(4)4:21:20 PM - Ended Loop #9750, Errors = 0
(5)4:21:20 PM - Ended Loop #9750, Errors = 0
(2)4:21:21 PM - Ended Loop #10000, Errors = 0
(1)4:21:21 PM - Ended Loop #10000, Errors = 0
(3)4:21:21 PM - Ended Loop #10000, Errors = 0
(4)4:21:21 PM - Ended Loop #10000, Errors = 0
(5)4:21:21 PM - Ended Loop #10000, Errors = 0
(0)4:21:21 PM - Ended
Average: 1566 pings/sec
C:\>
4.2 Java Sample 2
This Java sample program shows how you can use the MONITOR service to
log a message to update the status of the test.
The syntax to run this program is:
C:\>java com.ibm.staf.service.stax.TestProcess
Usage: java TestProcess loopCount incrementSeconds returnCode
where:
This program submits a LOG request to the MONITOR service stating which loop
it is currently running. It submits a MONITOR LOG request at the beginning
of each loop and then sleeps the specified number of incrementSeconds.
When complete, it returns the specified returnCode.
/*****************************************************************************/
/* Software Testing Automation Framework (STAF) */
/* (C) Copyright IBM Corp. 2002 */
/* */
/* This software is licensed under the Common Public License (CPL) V1.0. */
/*****************************************************************************/
import com.ibm.staf.*;
import java.util.*;
public class TestProcess implements Runnable
{
private STAFHandle handle = null;
private int counter;
private int loopCounter;
private int incrementSeconds;
private int returnCode;
public static void main(String[] args)
{
if (args.length < 3)
{
System.out.println("Usage: java TestProcess loopCount" +
" incrementSeconds returnCode");
System.exit(1);
}
try
{
int loopCounter = (new Integer(args[0])).intValue();
int incrementSeconds = (new Integer(args[1])).intValue();
int returnCode = (new Integer(args[2])).intValue();
TestProcess testProcess = new TestProcess(loopCounter,
incrementSeconds,
returnCode);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public TestProcess(int loopCounter, int incrementSeconds,
int returnCode)
{
this.loopCounter = loopCounter;
this.incrementSeconds = incrementSeconds;
this.returnCode = returnCode;
this.run();
}
public void run()
{
try
{
// register with STAF
handle = new STAFHandle("TestProcess");
System.out.println("STAF handle: " + handle.getHandle());
STAFResult res = handle.submit2(
"local", "VAR",
"RESOLVE STRING {STAF/Config/MachineNickname}");
if (res.rc != 0)
{
System.out.println(
"Error resolving {STAF/Config/MachineNickname}." +
" RC: " + res.rc + " Result: " + res.result);
terminate();
}
System.out.println(
"STAF/Config/MachineNickname: " + res.result);
}
catch(STAFException e)
{
System.out.println("Error registering with STAF");
terminate();
}
for (int i=0; i < loopCounter; i++)
{
STAFResult result = handle.submit2(
"local", "monitor", "log message " +
STAFUtil.wrapData("Loop #" + String.valueOf(i)));
System.out.println("Loop #" + String.valueOf(i));
try
{
Thread.sleep(incrementSeconds * 1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
terminate();
}
public void terminate()
{
try
{
if (handle != null)
{
handle.submit2("local", "monitor", "log message " +
STAFUtil.wrapData("Terminating "));
// unregister
handle.unRegister();
}
}
catch(STAFException e)
{
/* do nothing */
}
finally
{
System.exit(returnCode);
}
}
}
Here's an example of running the sample program:
C:\dev\sf\src\staf\test>java TestProcess 3 2 0
STAF handle: 127
STAF/Config/MachineNickname: sharon
Loop #0
Loop #1
Loop #2
C:\>
While this program is running, you can query the MONITOR
service to see get the latest message that the TestProcess
program logged. For example:
C:\>staf local monitor query machine sharon handle 118
Response
--------
Date-Time: 20050516-17:08:44
Message : Loop #0
C:\>staf local monitor query machine sharon handle 118
Response
--------
Date-Time: 20050516-17:08:49
Message : Loop #1
C:\>staf local monitor query machine sharon handle 118
Response
--------
Date-Time: 20050516-17:08:54
Message : Loop #2
C:\>staf local monitor query machine sharon handle 118
Response
--------
Date-Time: 20050516-17:08:59
Message : Terminating
*** End of Document ***