Last Updated: May 17, 2005
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 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 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); }
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.
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(); }
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);
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.
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); }
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");
C:\>java JPing Usage: java JPingFor 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.[# Threads] [# Loops per thread] [Display Modulus] Defaults: # Threads = 5 # Loops per thread = 10000 Display Modulus = 250 Examples: java JPing local java JPing SomeServer 3 1000 100
/*****************************************************************************/ /* 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:\>
C:\>java com.ibm.staf.service.stax.TestProcess Usage: java TestProcess loopCount incrementSeconds returnCodewhere:
/*****************************************************************************/ /* 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