Last Updated: June 27, 2014
STAF Java support must be installed in order to submit requests to STAF via a Java program or to register a STAF Java service such as STAX, Event, Cron, EventManager, Email, etc.
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.
To verify that the version of Java you are using works with STAF Java support, run TestJSTAF as decribed in section 5.0 How to Test STAF Java Support.
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 the primary class used to communicate with STAF. It is used to register with STAF, submit service requests to STAF, and unregister with STAF. Each Java application should generally create one and only one STAFHandle object. The act of creating this object registers the Java application with STAF.
There are two constructors for the STAFHandle class:
Once you have a valid STAFHandle instance object, you can begin submitting requests to STAF services by one of two methods:
Note that a STAFHandle instance object has a auto-unmarshall result member variable that defaults to true when a STAFHandle instance object is created, but can be set to false via its setDoUnmarshallResult() method. When set to true, this causes STAF results to be automatically unmarshalled when using the submit2() method.
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(); // Set a flag to indicates whether the result should be auto-unmarshalled // Added in STAF V3.3.1 public void setDoUnmarshallResult(boolean flag); // Retrieve the auto-unmarshall result flag // Added in STAF V3.3.1 public boolean getDoUnmarshallResult(); }
import com.ibm.staf.*; import java.io.*; public class STAFTest { public static void main(String argv[]) { try { // Create a STAFHandle STAFHandle handle = new STAFHandle("MyApplication"); System.out.println("My handle is: " + handle.getHandle()); try { // Submit a synchronous request to the ECHO service on // the local machine STAFResult result = handle.submit2( "local", "ECHO", "ECHO Hello"); if (result.rc != 0) { System.out.println( "ERROR: STAF local ECHO ECHO Hello failed. RC: " + result.rc + ", Result: " + result.result); } else { System.out.println("ECHO Result: " + result.result); } // Or submit an asynchronous request to the ECHO service on // the local machine result = handle.submit2( STAFHandle.ReqRetain, "local", "ECHO", "ECHO Hello"); if (result.rc != 0) { System.out.println( "ERROR: STAF local ECHO ECHO Hello failed. RC: " + result.rc + ", Result: " + result.result); } else { System.out.println( "Asynchronous ECHO Request number: " + result.result); } } 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
import com.ibm.staf.*; public class STAFTest { public static void main(String argv[]) { try { // Create a STAFHandle STAFHandle handle = new STAFHandle("MyApplication"); System.out.println("My handle is: " + handle.getHandle()); // Submit some requests to STAF services String machine = "local"; String service = "PING"; String request = "PING"; try { // Submit a synchronous request to the PING service on // the local machine String result = handle.submit(machine, service, request); System.out.println("PING Result: " + result); // Submit an asynchronous STAF request to the PING service // on the local machine result = handle.submit( STAFHandle.ReqQueueRetain, machine, service, request); System.out.println("PING Request number: " + result); } catch (STAFException e) { System.out.println( "Error submitting STAF " + machine + " " + service + " " + request); System.out.println("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
import com.ibm.staf.*; public class STAFTest { public static void main(String argv[]) { try { // Create a STAFHandle (non-static) STAFHandle handle = new STAFHandle("MyApplication"); System.out.println("My non-static handle is: " + handle.getHandle()); STAFHandle staticHandle = null; int staticHandleNumber = 0; try { // Create a STAF static handle STAFResult result = handle.submit2( "local", "HANDLE", "CREATE HANDLE NAME MyStaticHandleName"); if (result.rc != STAFResult.Ok) { System.exit(1); } staticHandleNumber = new Integer(result.result).intValue(); staticHandle = new STAFHandle(staticHandleNumber); System.out.println("My static handle is: " + staticHandleNumber); // Request a mutex semaphore using the static STAFHandle to // submit the request System.out.println("Request mutex semaphore MyMutex"); result = staticHandle.submit2( "local", "SEM", "REQUEST MUTEX MyMutex"); if (result.rc != STAFResult.Ok) { System.out.println( "ERROR: STAF local SEM REQUEST MUTEX MyMutex failed. RC: " + result.rc + ", Result: " + result.result); System.exit(1); } // Do whatever else you want to do } finally { if (staticHandleNumber != 0) { // Release the mutex semaphore using the static STAFHandle // to submit the request System.out.println("Release mutex semaphore MyMutex"); STAFResult result = staticHandle.submit2( "local", "SEM", "RELEASE MUTEX MyMutex"); // Delete the static handle System.out.println("Delete static handle"); result = handle.submit2( "local", "HANDLE", "DELETE HANDLE " + staticHandleNumber); } 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
import com.ibm.staf.*; import java.util.*; public class STAFTest { public static void main(String argv[]) { try { // Create a STAFHandle STAFHandle handle = new STAFHandle("MyApplication"); System.out.println("My handle is: " + handle.getHandle()); try { // Submit a request to the PROCESS service to run a command on // a machine and wait for it to complete and returns its stdout // and stderr. Note that the result from this request returns // a marshalled map so we'll use STAFResult's resultObj variable // to access the map root object String machine = "local"; String command = "dir \\temp"; String service = "PROCESS"; String request = "START SHELL COMMAND " + STAFUtil.wrapData(command) + " WAIT RETURNSTDOUT STDERRTOSTDOUT"; STAFResult result = handle.submit2(machine, service, request); if (result.rc != 0) { System.out.println( "ERROR: STAF " + machine + " " + service + " " + request + " RC: " + result.rc + ", Result: " + result.result); System.exit(1); } // The command was started successfully. Check the process // return code and if non-zero, also print an error message Map resultMap = (Map)result.resultObj; String processRC = (String)resultMap.get("rc"); if (!processRC.equals("0")) { System.out.println( "ERROR: Process RC is not 0.\n" + result.resultContext); System.exit(1); } // Print the stdout/stderr data for the command List returnedFileList = (List)resultMap.get("fileList"); Map stdoutMap = (Map)returnedFileList.get(0); String stdoutData = (String)stdoutMap.get("data"); System.out.println("Process Stdout:\n" + stdoutData); } 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. In addition, if auto-unmarshalling is enabled for the handle (which it is by default), the STAFResult object also contains the marshalling context for the result (e.g. the unmarshalled result) and the result object (e.g. the root object of the marshalling context). Otherwise, if auto-unmarshalling is disabled for the handle that called the submit2() method, the resultContext and resultObj fields will be set to null. It is typically used in places where you wish to avoid catching exceptions when using STAF or where you want the result to be auto-unmarshalled. 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); // Added in STAF V3.3.1 STAFResult(int theRC, String theResult, boolean doUnmarshallResult); public int rc; public String result; public Object resultObj = null; // Added in STAF V3.3.1 public STAFMarshallingContext resultContext = null; // Added in STAF V3.3.1 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 CreateThreadError = 57; public static final int MaximumSizeExceeded = 58; public static final int MaximumHandlesExceeded = 59; // Added in STAF V3.3.6 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); }
import com.ibm.staf.*; import java.util.*; // The variable "handle" is an instance of the STAFHandle class that was // previously instantiated. String dirName = "{STAF/Config/STAFRoot}/bin"; String request = "LIST DIRECTORY " + STAFUtil.wrapData(dirName) + " TYPE F LONG"; STAFResult result = handle.submit2("local", "FS", request); if (result.rc == STAFResult.Ok) { // The result buffer from a successful LIST DIRECTORY LONG request // returns a marshalled list of maps containing information about // the entries in the directory System.out.println("Successful FS " + request + "\nResult=" + result.resultContext); // Iterate through the unmarshalled result (which is a List // containing a Map for each entry in the directory) and // check which files have a last modified data > 20140101-00:00:00 List resultList = (List)result.resultObj; Iterator iter = resultList.iterator(); while (iter.hasNext()) { Map entryMap = (Map)iter.next(); String lmTimestamp = (String)entryMap.get("lastModifiedTimestamp"); if (lmTimestamp.compareTo("20140101-00:00:00") == 1) { System.out.println("File " + entryMap.get("name") + " was last modified on " + lmTimestamp); } } } else { System.out.println("Error submitting FS " + request + "\nRC: " + result.rc + " Result: " + result.result); }
These APIs allow you to define, manipulate, and (un)marshall data structures, and print marshalled data in human-readable ("pretty" print) format.
STAF supports the automatic marshalling and unmarshalling of structured data. The act of marshalling takes a data structure and converts it into a string-based representation. The act of unmarshalling reverses this and converts the string-based representation back into a data structure. See Section 6.1, "Marshalling Structured Data" in the STAF User's Guide for more information.
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 STAFMapClassDefinition object that you want to return.
The required argument mapClassName specifies a String containing the name of the STAFMapClassDefinition object that you want to check if the marshalling context's contains in its list of map class definitions.
Note that the name of a map class definition is a String.
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 data is a string to be unmarshalled.
The required argument context specifies the STAFMarshallingContext object that should be used when unmarshalling the string. You can specify null for this argument.
The required argument data is a string to be unmarshalled.
The required argument context specifies the STAFMarshallingContext object that should be used 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}"; try { String result = handle.submit(machine, service, request); // The result from the request is a marshalled list of strings. // Unmarshall the result. STAFMarshallingContext mc = STAFMarshallingContext.unmarshall( result); // Pretty print the result context System.out.println("Formatted output:\n" + mc); 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"); } } } catch (STAFException e) { System.out.println( "Error submitting request STAF " + machine + " " + service + " " + request + "\nRC: " + e.rc + " Result: " + e.getMessage()); } } private static STAFHandle handle; }
Formatted output: [ lib codepage STAFInst STAFInst.mfs samples include bin LICENSE.htm docs data services NOTICES.htm install.properties ] 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 : <None> Files : [ { Return Code: 0 Data : Volume in drive C has no label. Volume Serial Number is 88AF-B0AF Directory of C:\STAF 06/23/2014 02:30 PM <DIR> . 06/23/2014 02:30 PM <DIR> .. 06/23/2014 02:31 PM <DIR> bin 06/23/2014 02:30 PM <DIR> codepage 03/05/2010 03:01 PM <DIR> data 06/23/2014 02:30 PM <DIR> docs 06/23/2014 02:30 PM <DIR> include 06/23/2014 02:30 PM 139 install.properties 06/23/2014 02:30 PM <DIR> jre 06/23/2014 02:30 PM <DIR> lib 06/17/2014 07:15 PM 17,029 LICENSE.htm 06/17/2014 07:15 PM 8,516 NOTICES.htm 06/23/2014 02:30 PM <DIR> samples 03/28/2014 10:34 AM <DIR> services 06/23/2014 02:29 PM 275 STAFEnv.bat 06/23/2014 02:30 PM 71,365 STAFInstall.log 12/09/2010 06:49 PM 21 STAFReg.inf 06/23/2014 02:29 PM 147 startSTAFProc.bat 06/23/2014 02:30 PM 2,238 startSTAFProc.ico 06/23/2014 02:30 PM <DIR> Uninstall_STAF 8 File(s) 99,730 bytes 12 Dir(s) 106,599,550,976 bytes free } ] }
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 SHELL COMMAND " + STAFUtil.wrapData(command) + " RETURNSTDOUT STDERRTOSTDOUT WAIT"; System.out.println( "STAF " + machine + " " + service + " " + request); try { String result = handle.submit(machine, service, request); // 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); 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); } catch (STAFException e) { System.out.println( "Error submitting request STAF " + machine + " " + service + " " + request + "\nRC: " + e.rc + " Result: " + e.getMessage()); } } private static STAFHandle handle; }
STAF local PROCESS START SHELL COMMAND :26:dir {STAF/Config/STAFRoot} RETURNSTDOUT STDERRTOSTDOUT WAIT
Process Stdout File Contains: Volume in drive C has no label. Volume Serial Number is 88AF-B0AF Directory of C:\STAF 06/23/2014 02:30 PM <DIR> . 06/23/2014 02:30 PM <DIR> .. 06/23/2014 02:31 PM <DIR> bin 06/23/2014 02:30 PM <DIR> codepage 03/05/2010 03:01 PM <DIR> data 06/23/2014 02:30 PM <DIR> docs 06/23/2014 02:30 PM <DIR> include 06/23/2014 02:30 PM 139 install.properties 06/23/2014 02:30 PM <DIR> jre 06/23/2014 02:30 PM <DIR> lib 06/17/2014 07:15 PM 17,029 LICENSE.htm 06/17/2014 07:15 PM 8,516 NOTICES.htm 06/23/2014 02:30 PM <DIR> samples 03/28/2014 10:34 AM <DIR> services 06/23/2014 02:29 PM 275 STAFEnv.bat 06/23/2014 02:30 PM 71,365 STAFInstall.log 12/09/2010 06:49 PM 21 STAFReg.inf 06/23/2014 02:29 PM 147 startSTAFProc.bat 06/23/2014 02:30 PM 2,238 startSTAFProc.ico 06/23/2014 02:30 PM <DIR> Uninstall_STAF 8 File(s) 99,730 bytes 12 Dir(s) 106,599,550,976 bytes free
The required argument obj specifies any Object to be formatted in a verbose, more readable format.
String request = "QUERY ENTRY {STAF/Config/ConfigFile}"; try { String result = handle("local", "FS", request); STAFMarshallingContext mc = STAFMarshallingContext.unmarshall(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); } catch (STAFException e) { System.out.println( "Error submitting request STAF local FS " + request + "\nRC: " + e.rc + " Result: " + e.getMessage()); }
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: 20140506-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: 20140506-16:08:08 }
These APIs allow you to handle private data. These APIs are all static methods in the STAFUtil class:
See Section 7.3, "Private Data" in the STAF User's Guide for more information about handling private data.
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 SHELL 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);
These are general utility APIs that you may find useful when writing test cases in Java or when writing a Java service.
The general utility APIs that are static functions in the STAFUtil class are:
Other general utility APIs are:
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 SHELL 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 parameter durationString specifies the timeout duration in the format <Number>[s|m|h|d|w]. For example: "100", "1s", "5m", "1h".
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 the converted duration in milliseconds. If not successful, a non-zero return code will be set and the result buffer will contain a detailed error message.
Since: STAF V3.3.2
public class STAFUtil { public static STAFResult convertDurationString(String durationString); }
STAFResult result = convertDurationString("10h"); if (result.rc != STAFResult.Ok) return result; try { long duration = Long.parseLong(result.result); } catch (NumberFormatException e) { return new STAFResult(STAFResult.InvalidValue, "NumberFormatException: " + e.getMessage()); }
Required parameter size specifies the size in the format <Number>[k|m]. For example: "1000000", "500k", "5m".
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 the converted size in bytes. If not successful, a non-zero return code will be set and the result buffer will contain a detailed error message.
Since: STAF V3.3.4
public class STAFUtil { public static STAFResult convertSizeString(String sizeString); }
long maxFileSizeInBytes = 0; STAFResult result = convertSizeString("5m"); if (result.rc != STAFResult.Ok) return result; try { maxFileSizeInBytes = Long.parseLong(result.result); } catch (NumberFormatException e) { // Should never happen because convertSizeString should have // returned an error previously return new STAFResult(STAFResult.InvalidValue, "NumberFormatException: " + e.getMessage()); }
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 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}"). This value specifies the timeout duration in the format <Number>[s|m|h|d|w]. For example: "100", "1s", "5m", "1h".
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 set to the duration value converted to milliseconds. If unsuccessful, the rc will be set to a non-zero integer and the result string will contain an error message.
Since: STAF V3.3.2
public class STAFUtil { public static STAFResult resolveRequestVarAndConvertDuration( String option, String value, STAFHandle handle, int requestNumber); }
if (parseResult.optionTimes("WAIT") > 0) { String waitString = parseResult.optionValue("WAIT"); String waitTimeout = ""; if (waitString.length() != 0) { // Resolve the WAIT value, verify that it is a valid // duration timeout value, and convert it to milliseconds // if needed resolvedValue = STAFUtil.resolveRequestVarAndConvertDuration( "WAIT", waitString, fHandle, info.requestNumber); if (resolvedValue.rc != STAFResult.Ok) return resolvedValue; waitTimeout = resolvedValue.result; } }
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}"). This value specifies the size in the format <Number>[k|m]. For example: "1000000", "500k", "5m".
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 set to the size value converted to bytes. If unsuccessful, the rc will be set to a non-zero integer and the result string will contain an error message.
Since: STAF V3.3.4
public class STAFUtil { public static STAFResult resolveRequestVarAndConvertSize( String option, String value, STAFHandle handle, int requestNumber); }
long maxFileSizeInBytes = 0; if (parseResult.optionTimes("MAXRETURNFILESIZE") > 0) { // Resolve the MAXRETURNFILESIZE value, verify that it is a // valid size value, and convert it to bytes, if needed resolvedValue = STAFUtil.resolveRequestVarAndConvertSize( "MAXRETURNFILESIZE", parseResult.optionValue("MAXRETURNFILESIZE"), fHandle, info.requestNumber); if (resolvedValue.rc != STAFResult.Ok) return resolvedValue; try { maxFileSizeInBytes = Long.parseLong(resolvedValue.result); } catch (NumberFormatException e) { // Should never happen because resolveRequestVarAndConvertSize // should have returned an error previously return new STAFResult( STAFResult.InvalidValue, "Invalid MAXRETURNFILESIZE value: " + resolvedValue.result); } }
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
"
a[.b[.c[.d]]] [text]where:
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:
"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"
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
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 ... } }
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[.b[.c[.d]]] [text]where:
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:
"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"
This method returns an integer 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."); }
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"); try { String result = handle.submit("local", "QUEUE", "GET WAIT"); STAFQueueMessage message = new STAFQueueMessage(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); } catch (STAFException e) { System.out.println( "Error getting message from queue, RC: " + e.rc + ", Additional Info: " + e.getMessage()); } } 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 : 20140516-12:31:42 Machine : local://local Handle name: STAF/Client Handle : 73 Type : MyType Message : Hi there C:>
These APIs are wrappers around the following LOG commands which can make it simple to submit LOG requests to the LOG and MONITOR services:
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");
These APIs are Java GUI classes that allow you to:
Note that the STAX Monitor Java application uses the STAFLogViewer class to display the STAX job logs and the STAX service log.
Since: STAF V3.1.0
To execute and get help from the STAFLogViewer class from the command line, specify the following:
java com.ibm.staf.STAFLogViewer -help
The STAFLogViewer class accepts the following command line options:
-queryRequest <LOG QUERY Request> -machine <Log Service Machine Name> -serviceName <Log Service Name> -levelMask <LEVELMASK option> -fontName <Font Name> -saveAsDirectory <Directory Name> -help -versionYou must specify -queryRequest or -help or -version.
-machine specifies the name of the machine where the STAF log is located. This optiontis optional. The default is local.
-serviceName specifies the name of the log service. This option is optional. The default is LOG.
-levelMask specifies the log levels to be initially displayed. This option 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 option is optional. The default is Monospaced. Examples of other fonts are Dialog and TimesRoman.
-saveAsDirectory specifies the initial directory path that will be used if you select the "File->Save As Text..." or "File->Save As Html..." menu item to save the log query output in a file. If not specified, it defaults to user's default directory which is typically the "My Documents" folder on Windows or the user's home directory on Unix.
-help displays help information for the STAFLogViewer. This option is optional.
-version displays the version of the STAFLogViewer. This option is optional.
You may also call the STAFLogViewer class from a Java application. The following constructors for STAFLogViewer are provided:
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) public STAFLogViewer(Component parent, STAFHandle handle, String machine, String serviceName, String queryRequest, String levelMask, String fontName, String saveAsDirectory)
Here is an example of the Java GUI that is displayed for the following command:
java com.ibm.staf.STAFLogViewer -machine staf1f.austin.ibm.com -queryRequest "QUERY machine {STAF/Config/MachineNickname} logname email all"
The STAFLogViewer's menu bar provides the following menus:
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");
A JVM Log file contains JVM start information such as the date/time when the JVM was created, the JVM executable, and the J2 options used to start the JVM. It also any other information logged by the JVM. This includes any errors that may have occurred while the JVM was running and any debug information output by a Java service. Also, the JVM Log for the STAX service contains the output from any print statements that are used within a <script> element in a STAX xml job file which is useful when debugging Python code contained in a <script> element. When a problem occurs with a STAF Java service, you should always check it's JVM Log as it may contain information to help debug the problem.
STAF stores JVM Log files in the {STAF/DataDir}/lang/java/jvm/<JVMName> directory. STAF retains a configurable number of JVM Logs (five by default) for each JVM. The current JVM log file is named JVMLog.1 and older saved JVM log files, if any, are named JVMLog.2 to JVMLog.<MAXLOGS>. When a JVM is started, if the size of the JVMLog.1 file exceeds the maximum configurable size (1M by default), the JVMLog.1 file is copied to JVMLog.2 and so on for any older JVM Logs, and a new JVMLog.1 file will be created.
When using the STAFJVMLogViewer, you can specify the machine where the STAF JVM log resides (e.g. where the Java service is registered) and you can specify/select the name of the STAF service whose JVM Log you want to display. This Java class submits requests to STAF, so STAF has to be running. This Java class can be run as an application via the command line or can be run via another Java program.
Note that the STAX Monitor Java application uses the STAFJVMLogViewer class to display the JVM log for the STAX service and for other services.
Since: STAF V3.2.1
java com.ibm.staf.STAFJVMLogViewer -help
The STAFJVMLogViewer class accepts the following command line options:
-machine <Machine where the STAF Java service is registered> -serviceName <Java Service Name> -displayAll -fontName <Font Name> -help -version
All of the options are optional. If specifying the -help or -version option, this option must be the first (and only) option specified.
-serviceName specifies the name of a Java service that is currently registered whose JVM Log you want to display. This option is optional. If it is not specified, you'll be prompted to select a service registered on the specified machine whose JVM Log you want to display.
-displayAll specifies to display all of the entries in the JVM Log. This option is optional. The default is to display only the entries in the JVM Log from the last time the JVM was created.
-fontName specifies the name of the font to use when displaying the STAF JVM Log. This option is optional. The default is Monospaced. Examples of other fonts are Dialog and TimesRoman.
-help displays help information for the STAFJVMLogViewer. This option is optional.
-version displays the version of the STAFJVMLogViewer. This option is optional.
You may also call the STAFJVMLogViewer class from a Java application. The following constructors for STAFJVMLogViewer are provided:
public STAFJVMLogViewer(Component parent, STAFHandle handle, String serviceName) public STAFJVMLogViewer(Component parent, STAFHandle handle, String machine, String serviceName) public STAFJVMLogViewer(Component parent, STAFHandle handle, String machine, String serviceName, boolean displayAll, String fontName)
Here is an example of the Java dialogs that are displayed for the following command:
java com.ibm.staf.STAFJVMLogViewer -machine staf1a
Click on the drop-down list to see all of the Java services registered on this machine. Select a Java service, and then select the OK button to display the JVM Log for this Java service.
Here is an example of the dialog that is shown when the JVM Log is displayed.
The STAFJVMLogViewer's menu bar provides the following menus:
java com.ibm.staf.STAFJVMLogViewer -serviceName Cron
java com.ibm.staf.STAFJVMLogViewer -serviceName STAX -machine server1.company.com
java com.ibm.staf.STAFJVMLogViewer -machine server1.company.com
import com.ibm.staf.*; ... STAFJVMLogViewer logViewer = new STAFJVMLogViewer( this, // This is Swing component such as JFrame myHandle, // This is a STAFHandle object that you're already created "local", "STAX");
import com.ibm.staf.*; ... boolean displayAll = true; String cronServiceMachine = "server1.company.com"; String cronServiceName = "CRON"; String fontName = "Dialog"; STAFJVMLogViewer logViewer = new STAFJVMLogViewer( this, // This is Swing component such as JFrame fHandle, // This is a STAFHandle object that you're already created cronServiceMachine, cronServiceName, displayAll, fontName);
This Java class can be run as an application via the command line or can be run via another Java program. When run as an application, it submits the specified Log query request to query a STAF log on any machine currently running STAF and then formats the output as either html or text. Or, when run via a Java program that has already submitted a LOG QUERY request, you can use the STAFLogFormatter class to format the log query result as either html or text. You can specify various options including whether you want the formatted output written to a file.
Two format types are supported:
STAF local LOG QUERY GLOBAL LOGNAME test1 LAST 3 20131205-13:54:42 Info Step 1 of ScenarioB completed 20131205-13:54:45 Info Step 2 of ScenarioB completed 20131205-13:54:54 Pass Scenario completed
Note that the STAFLogViewer class uses the STAFLogFormatter class when you select File->Save As Text... or File->Save As Html....
Since: STAF V3.3.2
To execute and get help from the STAFLogFormatter class from the command line, specify the following:
java com.ibm.staf.STAFLogFormatter -help
The STAFLogFormatter class accepts the following command line options:
-queryRequest <LOG QUERY Request> -fileName <File Name> -type <html | text> -fontName <Font Name> -title <Title> -machine <Log Service Machine Name> -serviceName <Log Service Name> -help -versionYou must specify one of the following options: -queryRequest or -help or -version. If specifying the -help or -version option, it must be the first and only option specified. All of the other options require the -queryRequest option to be specified.
Here's a description of all of the options:
-fileName specifies the fully-qualified name of a file where the formatted log output will be written. This option is optional. If not specified, the formatted log output is written to Stdout.
-type specifies the format type. Valid values are: html or text. This option is optional. If not specified, it defaults to html.
-fontName specifies the name of the font to use when formatting the STAF log. It does not have an effect if formatting the log as text. This option is optional. If not specified, it defaults to courier (which is a Monospaced font). Examples of other valid font names are dialog and timesRoman.
-title specifies a title for the log output. This option is optional. If not specified, it defaults to the actual log query request submitted if using type html or to no title if using type text.
-machine specifies the name of the machine where the STAF log is located. This option is optional. If not specified, it defaults to local.
-serviceName specifies the name of the Log service to which the query request will be submitted. This option is optional. If not specified, it defaults to LOG.
-help displays help information for the STAFLogFormatter. This option is optional, but if specified, it must be the first and only option specified.
-version displays the version of the STAFLogFormatter. This option is optional, but if specified, it must be the first and only option specified.
package com.ibm.staf; public class STAFLogFormatter { public STAFLogFormatter(STAFMarshallingContext context) throws STAFException public void setFileName(String fileName) public void setFontName(String fontName) public void setTitle(String title) public String format(String typeString) throws IOException, STAFException }
When constructing a new STAFLogFormatter object, the required argument context must be a STAFMarshallingContext object containing a LOG QUERY result's marshalling context. >A STAFException is thrown if an invalid STAFMarshallingContext object is specified.
Class STAFLogFormatter defines the following methods:
The required argument fileName is a String containing the file name.
The required argument fileName is a String containing the font name.
The required argument title is a String containing the title for the formatted log output.
The required argument typeString must be a String containing the format type html or text, case-insensitive.
This method returns a string as follows:
A STAFException is thrown if an invalid STAFMarshallingContext object was specified when constructing the STAFLogFormatter.
A IOException is thrown if a fileName is set and there is a problem writting the formatted log output to the specified fileName.
C:\>java com.ibm.staf.STAFLogFormatter -type text -machine client1.company.com -queryRequest "QUERY GLOBAL LOGNAME test1 LAST 7" 20131205-13:53:57 Info Step 1 of ScenarioA completed 20131205-13:54:06 Info Step 2 of ScenarioA completed 20131205-13:54:12 Info Step 3 of ScenarioA completed 20131205-13:54:27 Pass ScenarioA completed 20131205-13:54:42 Info Step 1 of ScenarioB completed 20131205-13:54:45 Info Step 2 of ScenarioB completed 20131205-13:54:54 Pass Scenario completed
C:\>java com.ibm.staf.STAFLogFormatter -fileName C:\logs\job1.html -queryRequest "QUERY MACHINE {STAF/Config/MachineNickname} LOGNAME STAX_Job_1 ALL"
String logName = "STAX_Job_1"; String queryRequest = "QUERY MACHINE {STAF/Config/MachineNickname} " + "LOGNAME " + logName + " ALL"; STAFResult queryResult = fHandle.submit2("local", "LOG", queryRequest); if ((queryResult.rc != STAFResult.Ok) && (queryResult.rc != 4010)) { System.out.println( "Log query request failed with RC=" + queryResult.rc + ", Result=" + queryResult.result); return; } try { STAFLogFormatter logFormatter = new STAFLogFormatter( queryResult.resultContext); logFormatter.setFileName("/logs/" + logName + ".html"); logFormatter.setTitle(logName + " Log"); logFormatter.setFontName("courier"); logFormatter.format("html"); } catch (Exception e) { System.out.println( "Formatting/saving the log as html failed.\n" + e.toString()); return; }
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 Eclipse Public License (EPL) 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 Eclipse Public License (EPL) 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: 20140516-17:08:44 Message : Loop #0 C:\>staf local monitor query machine sharon handle 118 Response -------- Date-Time: 20140516-17:08:49 Message : Loop #1 C:\>staf local monitor query machine sharon handle 118 Response -------- Date-Time: 20140516-17:08:54 Message : Loop #2 C:\>staf local monitor query machine sharon handle 118 Response -------- Date-Time: 20140516-17:08:59 Message : Terminating
The TestJSTAF class allows you to submit a command-line STAF request using the STAF Java support. This class is useful if you want to verify that the STAF Java support is working correctly, without requiring a GUI display or any modifications to the CLASSPATH.
The syntax of this class is:
Usage: java com.ibm.staf.TestJSTAF <Endpoint | LOCAL> <Service> <Request>
C:\> java com.ibm.staf.TestJSTAF LOCAL MISC VERSION TestJSTAF using STAF handle 15 RC=0 Result=3.4.18 C:\> c:\jdk1.7.0\jre\bin\java com.ibm.staf.TestJSTAF LOCAL PING PING TestJSTAF using STAF handle 19 RC=0 Result=PONG C:\> java com.ibm.staf.TestJSTAF machineA.company.com VAR RESOLVE STRING {STAF/Config/OS/Name} TestJSTAF using STAF handle 27 RC=0 Result=Win7