Red Hat Training

A Red Hat training course is available for Red Hat JBoss Operations Network

3. Using Script Modules for Dependencies and Loading Custom Functions

When automating management tasks or creating clients to interact withJBoss ON, it is frequently necessary to create custom classes and functions. The JBoss ON CLI implements CommonJS to support script modules.

Note

Script modules can be either JavaScript or Python files.

3.1. About Script Dependencies and Exporting Functions

When executing a script from a file by using the rhq-cli.sh -f option, there is no way to define an explicit dependency within an external file. Any functions required by that script must be contained in the script or accessible to the script.
The JBoss ON CLI uses CommonJS to support script modules. CommonJS is designed as a loading mechanism to express dependencies between scripts. If a script is in the default modules directory, then the script can be loaded into the CLI session or referenced in a script, and any exported function is available to the CLI. Modules can be used to load other modules into the CLI session, as well.
The only part of a script that is exposed is a function prepended with exports (following the CommonJS convention).
For example, the sample util.js file exports a foreach function which can search for any object in JBoss ON, as generic objects, arrays, criteria (search) objects, or maps.
exports.foreach = function (obj, fn) {
  var criteriaExecutors = {
  Alert: function(criteria) { return AlertManager.findAlertsByCriteria(criteria); },
  ... 8< ...
  }
All of the functions and objects that are not exported are private and cannot be used outside the module.
A module can be loaded into another mdule (creating a dependency) by listing the other module as a requirement.
var printResults = require("modules:/samples/modules/util.js");

Note

Only an exported function is available, and then it is only available through a variable defined in the script. For example, for the printResults variable, the foreach function is available, referenced as printResults.foreach.
This means that difference script modules can have functions defined in them with the same name, but because there are different variable namespaces, there is no conflict.

3.2. Default Locations for Script Module Sources

The require statement loads a modules from an identified location to be used in a script. The JBoss ON CLI, CLI script, or server-side script can load a module from any of several locations, for both the local and remote sources.
The require line has the format sourceType:/path/moduleFile.
The default module locations are defined in the following list.
Modules Directory
Description — Loads the specified module file from a configured location on the local system. The CLI has a system property (rhq.scripting.modules.root-dir) which defines a default root directory for modules. The modules location value then sets a subdirectory, within that root, where the module is located.
The location can be set or changed by updating the Java properties in the rhq-cli-env.sh file:
RHQ_CLI_ADDITIONAL_JAVA_OPTS='-Drhq.scripting.modules.root-dir=/opt/rhq/modules' bin/rhq-cli.sh
Format — modules:/relative-path
Example:
var myModule = require("modules:/myCompany/production/serverLocations"); //This will load the module from a file called "serverLocations.js" from a file that is located in the "myCompany/production" directory under a configured "root-dir" location.
Available For — CLI
Local Filesystem
Loads the specified module file from an absolute path on the local system.
Format — file:/path
Example:
var myModule = require("file:/opt/jon/js-modules/myModule"); //This will load the module from a file called "myModule.js" in the /opt/jon/js-modules directory on the local filesystem.
Available For — CLI
JBoss ON Repository
Downloads the specified module file from the given JBoss ON repository. Because this connects to the server, a user must be logged into the JBoss ON server first.
Format — rhq://repositories/repo_name/module_name
Example:
var myModule = require("rhq://repositories/myRepo/myModule"); //This will load the module stored in the RHQ server repository "myRepo" called "myModule.js"
Available for — CLI
JBoss ON Downloads
Downloads the specified module file from the downloads location on the JBoss ON server. JBoss ON could make some scripts available that can be used for alert server-side scripts or for the CLI. Because this connects to the server, a user must be logged into the JBoss ON server first.
Format — rhq://downloads/path/module_name
Example:
var myModule = require("rhq://downloads/script-modules/util"); //This will load the module stored in the RHQ server downloads section called "js/util.js"
Available For — CLI, Server

3.3. Creating a New Module Source Type

JBoss ON can load a CommonJS script module from different locations, including both local directories and remote repositories.
It is possible to create support for loading modules from a different source, such as a URL. Creating a new module source location requires three things:
  • Creating a new ScriptSourceProvider interface.
  • Adding the Java service entry in the META-INF/services directory of a JAR for the class.
  • Putting the new JAR into the lib/ directory of the CLI installation directory to be available to clients and in serverRoot/jon-server-3.2/modules/org/rhq/server-startup/main/deployments/rhq.ear/lib on the JBoss ON server so that it is available to server-side scripts (alert scripts).

Example 1. HTTP Module Source Location

This script source provider downloads a script module from a given URI as long as te Java version supports HTTP or HTTPS protocols.
  public class URLScriptSourceProvider implements ScriptSourceProvider {
  public Reader getScriptSource(URI scriptUri) {
  if (scriptUri == null) {
  return null;
  }
  try {
  return new InputStreamReader(scriptUri.toURL().openStream())
  } 
  catch (MalformedURLException e) {
  return null;
  } 
  catch (IOException e) {
  return null;
  }
  }
}
In the META-INF directory of the script provider JAR, create a services directory.
Then, within the META-INF/services/ directory, create a file called org.rhq.scripting.ScriptSourceProvider. Put the full class names of any source providers implemented in the JAR, one per line. For example, if the URLScriptSourceProvider is the only source provider:
com.example.URLScriptSourceProvider
This is the layout of the JAR:
* com
* example 
* URLScriptSourceProvider.class
* META-INF 
* services 
* org.rhq.scripting.ScriptSourceProvider
This JAR must then ba added to the lib of the CLI installation directory. After that, scripts run through the JBoss ON CLI on that system can use the HTTP provider to download the file from the network:
var myModule = require("http://server.example.com/rhq-scripts/stuff.js");
For the same source provider to be available to alert scripts, the JAR needs to be added to the modules/org/rhq/server-startup/main/deployments/rhq.ear/lib/ directory of the JBoss ON server.