In this article, we will modify the decision tree script that is part of the resource model created in Creating a simple resource model for processing Common Base Events from a file and add script fragments that call Java code. To illustrate this, we will create Java code to parse Common Base Events using utility classes from the Hyades Common Base Event implementation and code to correlate Common Base Events using a state-based approach.
This article assumes you have installed the Resource Model Builder, the Autonomic Management Engine, and the Generic Log Adapter for Autonomic Computing, all available as part of the Autonomic Computing Toolkit (see Resources). It also assumes that you know how to build resource models using the Resource Model Builder, how to deploy the resource models, and how to start the autonomic management engine. If not, take a look at the developerWorks article Creating a simple resource model for processing Common Base Events from a file, which shows you how to do all of these tasks. Also, you must install the Problem Determination Scenario from the Autonomic Computing Toolkit to obtain the CanonicalSituationMonitor.zip file contained in the scenario. Because all you need from the scenario is the zip file CanonicalSituationMonitor.zip, use the do not check prerequisites option when you install the scenario. Information on how to download these components can be found in Resources.
Editing a resource model’s decision tree script to call batch files
To begin, look at how batch files and shell commands can be called from decision tree scripts in a resource model. If you followed the instructions in the referenced article, your resource model builder should now look like Figure 1 (when the source panel is selected).
Figure 1. Resource Model Builder with basic decision tree script
Within a decision tree script, you can use the
Svc.ShellCmd to execute any shell command by providing the shell command to be executed as a string argument.
Listing 1. Using Svc.ShellCmd
Svc.ShellCmd(“echo Hello World >> c:\\trial.log");
This adds the string “Hello World" to the trial.log file (note the use of \\ before the file name). To try this, scroll down to the
visitTree function in the decision tree script source panel and add the code shown in Listing 1 immediately following the variable definitions. Next, deploy and start the resource model. The trial.log file is created in the specified path and statements are added to it for each cycle. If no path is specified and only the file name is provided, the file is created by default in the same directory from which you ran sara.bat. Figure 2 shows the decision tree script with the
Svc.ShellCmd in the
Figure 2. Resource Model Builder with decision tree script containing call to a shell command
Similarly, any batch file can be called using the
Svc.ShellCmd function. If the output of the shell command/batch file goes to the console (StdOut), you cannot see the output when the batch file/shell command is called from inside the decision tree script when the resource model is executing with a running AME instance. However, the output is placed in the trace.log file of AME (in the sara\logs subdirectory found within the AME run time installation directory). Figure 3 shows how the trace.log file would look if we had used
echo Hello World as the string parameter for the function call in Listing 1. The return value of the shell command or batch file execution is returned when
Svc.ShellCmd is called and can be stored in a variable. However, note that this is the return value of the execution and usually not the actual output of the shell command or batch file unless the output is explicitly returned by the shell command or batch file.
Figure 3. trace.log file showing output of shell command called from the decision tree script
Creating the Java class for parsing Common Base Event strings
The resource model under consideration reads in as strings Common Base Events from the specified log file. So that different fields can be addressed and accessed using regular member references, it helps if you parse these strings into Common Base Event objects. The Hyades Common Base Event implementation provides utility functions to parse Common Base Event strings into Common Base Event objects. To create this code, you can use any IDE or compiler; we use WebSphere® Studio Application Developer (Application Developer) to create for parsing the Java code that will be called from the decision tree script. Ultimately, the code needs to reside within a JAR file.
It is important to note that the class to be called cannot be in the default package; it must have a package defined explicitly. Also, make sure that your Java code does not cause abnormal program termination (for example,
The code shown in Figure 4 takes in a string and parses it into a Common Base Event. To compile it successfully, you need a two JAR files: hlevents.jar and hlcore.jar. Make sure that these are included in the list of JAR files used for the build. You can find both of these files in the lib folder within the Generic Log Adapter installation folder.
Figure 4. Application Developer window showing Java code for parsing Common Base Event strings
Next, we create a JAR file that contains the compiled code. This is accomplished in Application Developer by exporting into a JAR file. We call this JAR file custom.jar. Save this JAR file together with hlevents.jar and hlcore.jar.
Editing the resource model’s decision tree script to call Java classes
You must import the classes into the resource model before the decision tree script can use them. To import any package into the decision tree script, use the
ImportPackage function, which takes the package name to be imported as a string argument. Place this function call at the top of the decision tree script before the variable definition section. To import custom packages (packages that are not part of the core packages that come with the Java Runtime Environment [JRE]), you must prefix the actual package name with Packages. Listing 2 shows the function call to import the java.util package and the function to import the code for parsing the Common Base Events.
Listing 2. Function calls to import java.util package
ImportPackage(java.util); // import package from Java Runtime Libraries ImportPackage(Packages.com.ibm.dw.ame); // import custom package
Note that you do not have to add the
.* at the end of the package specification as you would in the Java language.
Figure 5. Decision tree script with importPackage to import custom class files
Figure 6. Decision tree script showing Java object instantiation
visitTree function as shown in Figure 7 to call the parser when each Common Base Event string is processed.
Figure 7. Decision tree script showing modified visitTree function
Things to remember
Java-like package names: You do not need to provide a
.*at end of the package name provided as an argument to the
ImportPackagefunction call. In fact, doing so throws an exception when trying to create an instance of the resource model using the
mkrminstancecommand at the sara command line
Double quotes in package names: Do not enclose the package name within double quotes. This also throws an exception when trying to create an instance of the resource model
var CBEParser = new CBEParser();
Importing indirectly referenced classes: There is no need to import classes that are not explicitly used in variable declaration or object instantiations. For example, the
getCBEObjmethod of the
CBEParserclass returns an object of type
ICommonBaseEvent. However, there is no need to import the package containing the
ICommonBaseEventexplicitly with an
System.outin Java code:
System.outcalls are routed to the sara.bat console. The output of the sara.bat file and the
System.outcalls might overlap. Note than in the case of calling batch files or shell commands, console output was redirected to the Autonomic Management Engine's trace file (trace.log). You can try this by introducing a call to the
printItmethod of the
CBEParserclass; it prints the provided message with a timestamp prefixed to it.
System Calls: Care must be taken when writing the Java code that will be called from the decision tree script. Certain Java system calls can cause the Autonomic Management Engine to shut down. However, other Java system calls, like
Exceptions thrown from the Java class: If uncaught exceptions are thrown at run time, or your Java class contains explicit throws of run time exceptions, AME logs the exception in the trace.log file as an Error and discards processing of the decision tree script. So, in this example, if when reading each of the Common Base Events and processing them through the Java class, an exception is thrown, the entire processing stops and no more Common Base Events are read in. Therefore, it is important that your Java class has proper exception handling built into it. In the example,
tryExceptionmethod always throws an exception that is caught by AME and logged in the trace.log file, after which execution of the decision tree script is halted. You can try this by placing this method call in different places within the
visitTreefunction in the decision tree script and looking at the trace.log file to see how far along the script AME continued processing until it caught the exception and stopped processing.
Time consuming method calls: All method calls from the decision tree script execute in a blocking manner. So, if the method call takes some time to complete or if it is threaded, the decision tree script processing is suspended until the call returns. This is important because even if you have set the refresh interval for say x seconds ( requiring
visitTreeto be called every x seconds), if during the execution of the
visitTreefunction there is a method call that takes y seconds to return, if y > x, then the refresh interval effectively becomes greater than x (the exact value is not y always and is not deterministic). You must make sure that your methods return as quickly as possible, and that the refresh interval is set at a value that is a true indication of what the refresh interval will be in the worst case when a method call takes a while to complete. You can accomplish this by studying the return times of the methods that might be called and determining the best indicative refresh interval.
Threading: You can create threads in the methods being called, but you must create a way to capture the results returned by the thread. If the method being called creates a thread and executes a
join()operation on the thread before returning, then you only need to be aware of the previous issue with time consuming method calls. However, if the thread is created and the method call returns, the decision tree script no longer has a handle to the thread and cannot receive the results of processing performed by the thread. In this case, either the calling method must return the thread handle to the decision tree script so that it can be queried later for completion and availability of the results, or there must be some other method call in the class that can provide the results of the processing. The former tightly couples the decision tree script with the thread, which might not be wanted because the thread is, in effect, created by the other class. Such an alternative might be required even when you do want to perform asynchronous method calls. For example, consider that the analysis is performed by an external component (set of Java classes) and the analysis requires multiple Common Base Events. In each cycle, the AME reads new Common Base Events and sends them to the analysis component, which returns immediately. The results of the analysis can be retrieved from the analysis component through another method call. Therefore, in each iteration, the decision tree script must make a call to the analysis component to see if the results are available.
Static methods: Static methods can be called by specifying the class name after the class has been imported using the mechanisms described above (it is not necessary to have created objects of these classes). Static members of a Java class can also be accessed provided they are explicitly defined as public (default does not work and throws an exception that stops processing of the decision tree script).
nullmight also be passed as a parameter, which might lead to some issues if proper exception handling is not built in the
Modifications to sara.bat
The AME run time needs to know where the JAR files that contain classes referenced from decision tree scripts are. Modify the sara.bat file and add the hlevents.jar, hlcore.jar, and custom.jar to the classpath used by the AME run time. Assume that these jar files are in the c:\autonomic subdirectory.
Open the sara.bat file in any editor and scroll down to the last occurrence of
SET CLASSPATH=……. .
Add another line with
SET CLASSPATH = %CLASSPATH%; c:\autonomic\hlevents.jar; c:\autonomic\hlcore.jar; c:\autonomic\custom.jar.
Alternately, you can put the JAR files in the lib of the AME run time installation; these JAR files are then automatically picked up. However, note that all the required JAR files must be placed together in this folder. For example, if only the custom.jar file is put in this folder, even if the other location of hlcore.jar and hlevents.jar is specified in the sara.bat file, an exception is thrown because AME will look for the other two JAR files in the same folder as custom.jar. Also, this folder takes priority over any others specified in the sara.bat file. Therefore, if version 1 of custom.jar is present in this folder and version 2 of custom.jar is elsewhere, but specified using
SET CLASSPATH in the sara.bat file, version 1 is always used.
The second method suggested above is recommended; some operating systems have problems with long values for environment variables (such as
CLASSPATH) and might ignore JAR files specified toward the end (assuming JAR files are appended to the end of the current
CLASSPATH). This becomes a very real problem when the JAR files are present in a deeply nested folder structure.
In this article, you have learned how to call Java classes from the decision tree scripts as well as the associated setup. You have also been given some guidance on issues that can potentially cause your decision tree scripts to fail and hints on what you can do to smoothly integrate Java code with the decision tree script.
- Download the custom.jar and Decision tree script used as examples in this article. The JAR file contains source code as well.
- Creating a simple resource model for processing Common Base Events from a file (developerWorks, June 2004) take you through the steps of how to use the Autonomic Computing Toolkit's Resource Model Builder to create a simple resource model for the AME that is capable of processing Common Base Events stored in a file and how to modify the decision tree script.
- Browse for books on these and other technical topics.