A common use case for management tools is to automate deployments of new or existing applications. This example creates an easy script for basic management tasks:
Find all JBoss EAP instances for a specified JBoss ON group.
Shut down each EAP instance.
Update binaries for existing deployed applications or create new deployments.
Restart the EAP instance.
End the loop.
Note
Different resource types have configuration properties and operations available, which can impact CLI scripts written to manage those resources. This can be true even for different versions of the same application — which is the case with JBoss AS 4 and JBoss AS 5 resources.
JBoss AS 4 and JBoss AS 5 have different APIs for operations like shutting down instances. In this example, separate scripts are shown for the two resource types. It is also possible to create a CLI script which identifies the resource type and then calls the appropriate API.
This script will use two custom functions to deploy the packages to create new resources.
function usage() {
println("Usage: deployToGroup <fileName> <groupName>");
throw "Illegal arguments";
}
function PackageParser(fullPathName) {
var file = new java.io.File(fullPathName);
var fileName = file.getName();
var packageType = fileName.substring(fileName.lastIndexOf('.')+1);
var tmp = fileName.substring(0, fileName.lastIndexOf('.'));
var realName = tmp.substring(0, tmp.lastIndexOf('-'));
var version = tmp.substring(tmp.lastIndexOf('-') + 1);
var packageName = realName + "." + packageType;
this.packageType = packageType.toLowerCase();
this.packageName = packageName;
this.version = version;
this.realName = realName;
}
function usage() {
println("Usage: deployToGroup <fileName> <groupName>");
throw "Illegal arguments";
}
function PackageParser(fullPathName) {
var file = new java.io.File(fullPathName);
var fileName = file.getName();
var packageType = fileName.substring(fileName.lastIndexOf('.')+1);
var tmp = fileName.substring(0, fileName.lastIndexOf('.'));
var realName = tmp.substring(0, tmp.lastIndexOf('-'));
var version = tmp.substring(tmp.lastIndexOf('-') + 1);
var packageName = realName + "." + packageType;
this.packageType = packageType.toLowerCase();
this.packageName = packageName;
this.version = version;
this.realName = realName;
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Checking the JBoss ON Groups and Inventory
The script should have two command-line parameters. The first should be the path of the new application that is installed in the group. The second is the name of the group itself. These parameters are parsed in the script (as described in more detail in Section 4.4, “Passing Script Arguments in the JBoss ON CLI”).
For example:
if( args.length < 2 ) usage();
var fileName = args[0];
var groupName = args[1];
if( args.length < 2 ) usage();
var fileName = args[0];
var groupName = args[1];
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Next, check if the path is valid and if the current user can read it. This is done by using Java classes as shown here:
// check that the file exists and that we can read it
var file = new java.io.File(fileName);
if( !file.exists() ) {
println(fileName + " does not exist!");
usage();
}
if( !file.canRead() ) {
println(fileName + " can't be read!");
usage();
}
// check that the file exists and that we can read it
var file = new java.io.File(fileName);
if( !file.exists() ) {
println(fileName + " does not exist!");
usage();
}
if( !file.canRead() ) {
println(fileName + " can't be read!");
usage();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Verify that the group really exists on the JBoss ON server:
// find resource group
var rgc = new ResourceGroupCriteria();
rgc.addFilterName(groupName);
rgc.fetchExplicitResources(true);
var groupList = ResourceGroupManager.findResourceGroupsByCriteria(rgc);
// find resource group
var rgc = new ResourceGroupCriteria();
rgc.addFilterName(groupName);
rgc.fetchExplicitResources(true);
var groupList = ResourceGroupManager.findResourceGroupsByCriteria(rgc);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The important part here is the call the resources.
rgc.fetchExplicitResources(true);
rgc.fetchExplicitResources(true);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Check if there is a group found:
if( groupList == null || groupList.size() != 1 ) {
println("Can't find a resource group named " + groupName);
usage();
}
var group = groupList.get(0);
println(" Found group: " + group.name );
println(" Group ID : " + group.id );
println(" Description: " + group.description);
if( groupList == null || groupList.size() != 1 ) {
println("Can't find a resource group named " + groupName);
usage();
}
var group = groupList.get(0);
println(" Found group: " + group.name );
println(" Group ID : " + group.id );
println(" Description: " + group.description);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
After validating that there is a group with the specified name, check if the group contains explicit resources:
if( group.explicitResources == null || group.explicitResources.size() == 0 ) {
println(" Group does not contain explicit resources --> exiting!" );
usage();
}
var resourcesArray = group.explicitResources.toArray();
if( group.explicitResources == null || group.explicitResources.size() == 0 ) {
println(" Group does not contain explicit resources --> exiting!" );
usage();
}
var resourcesArray = group.explicitResources.toArray();
Copy to ClipboardCopied!Toggle word wrapToggle overflow
resourceArray now contains all resources which are part of the group. Next, check if there are JBoss AS 4 Server instances which need to be restarted before the application is deployed.
for( i in resourcesArray ) {
var res = resourcesArray[i];
var resType = res.resourceType.name;
println(" Found resource " + res.name + " of type " + resType + " and ID " + res.id);
if( resType != "JBossAS Server") {
println(" ---> Resource not of required type. Exiting!");
usage();
}
// get server resource to start/stop it and to redeploy application
var server = ProxyFactory.getResource(res.id);
}
for( i in resourcesArray ) {
var res = resourcesArray[i];
var resType = res.resourceType.name;
println(" Found resource " + res.name + " of type " + resType + " and ID " + res.id);
if( resType != "JBossAS Server") {
println(" ---> Resource not of required type. Exiting!");
usage();
}
// get server resource to start/stop it and to redeploy application
var server = ProxyFactory.getResource(res.id);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
This requires a group with only JBossAS Server resource types as top level resources. Now server contains the JBossAS instance. This requires re-reading the server because it needs to be fully populated. Internally, the CLI is using simple JPA persistence, and it is necessary to not always fetch all dependent objects.
Next, traverse all the children of the server instance and find the resource name of the application:
var children = server.children;
for( c in children ) {
var child = children[c];
if( child.name == packageName ) {
}
}
var children = server.children;
for( c in children ) {
var child = children[c];
if( child.name == packageName ) {
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
packageName is the name of the application without version information and path as shown in the JBoss ON GUI as deployed applications.
Create a backup of the original version of the application:
println(" download old app to /tmp");
child.retrieveBackingContent("/tmp/" + packageName + "_" + server.name + "_old");
println(" download old app to /tmp");
child.retrieveBackingContent("/tmp/" + packageName + "_" + server.name + "_old");
Copy to ClipboardCopied!Toggle word wrapToggle overflow
A copy of the old application with the server name decoded in path is available in the /tmp/ directory.
Shut down the server and upload the new application content to the server.
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Deploying the New Resource
At this point, existing application can be updated. The next step is to create the resource through the CLI and then deploy it to the JBoss server.
First, get the resource type for the application. This depends on several parameters:
The type of the application (e.g., WAR or EAR)
The type of the container the app needs to be deployed on (such as Tomcat or JBoss AS 4)
Note
All of the information about the resource type, such as the appType and appTypeName, is defined in the resource agent plug-in, in the rhq-plugin.xml descriptor. The attributes, configuration parameters, operations, and metrics for each default resource type are listed in the Resource Monitoring and Operations Reference.
For example:
var appType = ResourceTypeManager.getResourceTypeByNameAndPlugin( appTypeName, "JBossAS" );
if( appType == null ) {
println(" Could not find application type. Exit.");
usage();
}
var appType = ResourceTypeManager.getResourceTypeByNameAndPlugin( appTypeName, "JBossAS" );
if( appType == null ) {
println(" Could not find application type. Exit.");
usage();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Then get the package type of the application.
var realPackageType = ContentManager.findPackageTypes( appTypeName, "JBossAS" );
if( realPackageType == null ) {
println(" Could not find JBoss ON's packageType. Exit.");
usage();
}
var realPackageType = ContentManager.findPackageTypes( appTypeName, "JBossAS" );
if( realPackageType == null ) {
println(" Could not find JBoss ON's packageType. Exit.");
usage();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Each resource in JBoss ON has some configuration parameters, including the WARs or EARs deployed on a JBoss AS 4 resource. As with the descriptive information, this is defined in the resource type's agent plug-in, in the rhq-plugin.xml descriptor. To be able to create a new resource, these parameters need to be filled in.
// create deployConfig
var deployConfig = new Configuration();
deployConfig.put( new PropertySimple("deployDirectory", "deploy"));
deployConfig.put( new PropertySimple("deployZipped", "true"));
deployConfig.put( new PropertySimple("createBackup", "false"));
// create deployConfig
var deployConfig = new Configuration();
deployConfig.put( new PropertySimple("deployDirectory", "deploy"));
deployConfig.put( new PropertySimple("deployZipped", "true"));
deployConfig.put( new PropertySimple("createBackup", "false"));
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The property names can be retrieved by calling a list of supported properties by the package type by calling this method:
var deployConfigDef = ConfigurationManager.getPackageTypeConfigurationDefinition(realPackageType.getId());
var deployConfigDef = ConfigurationManager.getPackageTypeConfigurationDefinition(realPackageType.getId());
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Provide the package bits as a byte array:
var inputStream = new java.io.FileInputStream(file);
var fileLength = file.length();
var fileBytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, fileLength);
for (numRead=0, offset=0; ((numRead >= 0) && (offset < fileBytes.length)); offset += numRead ) {
numRead = inputStream.read(fileBytes, offset, fileBytes.length - offset);
}
var inputStream = new java.io.FileInputStream(file);
var fileLength = file.length();
var fileBytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, fileLength);
for (numRead=0, offset=0; ((numRead >= 0) && (offset < fileBytes.length)); offset += numRead ) {
numRead = inputStream.read(fileBytes, offset, fileBytes.length - offset);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Then, create the resource. The information is defined in the resource type's agent plug-in, in the rhq-plugin.xml descriptor. For example:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Make sure that the given JBoss AS 4 server instance is still running and that JBoss ON knows that it is running, or it will throw an exception saying that the JBoss ON agent is not able to upload the binary content to the server.
This script will use two custom functions to deploy the packages to create new resources.
function usage() {
println("Usage: deployToGroup <fileName> <groupName>");
throw "Illegal arguments";
}
function PackageParser(fullPathName) {
var file = new java.io.File(fullPathName);
var fileName = file.getName();
var packageType = fileName.substring(fileName.lastIndexOf('.')+1);
var tmp = fileName.substring(0, fileName.lastIndexOf('.'));
var realName = tmp.substring(0, tmp.lastIndexOf('-'));
var version = tmp.substring(tmp.lastIndexOf('-') + 1);
var packageName = realName + "." + packageType;
this.packageType = packageType.toLowerCase();
this.packageName = packageName;
this.version = version;
this.realName = realName;
}
function usage() {
println("Usage: deployToGroup <fileName> <groupName>");
throw "Illegal arguments";
}
function PackageParser(fullPathName) {
var file = new java.io.File(fullPathName);
var fileName = file.getName();
var packageType = fileName.substring(fileName.lastIndexOf('.')+1);
var tmp = fileName.substring(0, fileName.lastIndexOf('.'));
var realName = tmp.substring(0, tmp.lastIndexOf('-'));
var version = tmp.substring(tmp.lastIndexOf('-') + 1);
var packageName = realName + "." + packageType;
this.packageType = packageType.toLowerCase();
this.packageName = packageName;
this.version = version;
this.realName = realName;
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Checking the JBoss ON Groups and Inventory
The script should have two command-line parameters. The first should be the path of the new application that is installed in the group. The second is the name of the group itself. These parameters are parsed in the script (as described in more detail in Section 4.4, “Passing Script Arguments in the JBoss ON CLI”).
For example:
if( args.length < 2 ) usage();
var fileName = args[0];
var groupName = args[1];
if( args.length < 2 ) usage();
var fileName = args[0];
var groupName = args[1];
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Next, check if the path is valid and if the current user can read it. This is done by using Java classes as shown here:
// check that the file exists and that we can read it
var file = new java.io.File(fileName);
if( !file.exists() ) {
println(fileName + " does not exist!");
usage();
}
if( !file.canRead() ) {
println(fileName + " can't be read!");
usage();
}
// check that the file exists and that we can read it
var file = new java.io.File(fileName);
if( !file.exists() ) {
println(fileName + " does not exist!");
usage();
}
if( !file.canRead() ) {
println(fileName + " can't be read!");
usage();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Verify that the group really exists on the JBoss ON server:
// find resource group
var rgc = new ResourceGroupCriteria();
rgc.addFilterName(groupName);
rgc.fetchExplicitResources(true);
var groupList = ResourceGroupManager.findResourceGroupsByCriteria(rgc);
// find resource group
var rgc = new ResourceGroupCriteria();
rgc.addFilterName(groupName);
rgc.fetchExplicitResources(true);
var groupList = ResourceGroupManager.findResourceGroupsByCriteria(rgc);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The important part here is the call the resources.
rgc.fetchExplicitResources(true);
rgc.fetchExplicitResources(true);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Check if there is a group found:
if( groupList == null || groupList.size() != 1 ) {
println("Can't find a resource group named " + groupName);
usage();
}
var group = groupList.get(0);
println(" Found group: " + group.name );
println(" Group ID : " + group.id );
println(" Description: " + group.description);
if( groupList == null || groupList.size() != 1 ) {
println("Can't find a resource group named " + groupName);
usage();
}
var group = groupList.get(0);
println(" Found group: " + group.name );
println(" Group ID : " + group.id );
println(" Description: " + group.description);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
After validating that there is a group with the specified name, check if the group contains explicit resources:
if( group.explicitResources == null || group.explicitResources.size() == 0 ) {
println(" Group does not contain explicit resources --> exiting!" );
usage();
}
var resourcesArray = group.explicitResources.toArray();
if( group.explicitResources == null || group.explicitResources.size() == 0 ) {
println(" Group does not contain explicit resources --> exiting!" );
usage();
}
var resourcesArray = group.explicitResources.toArray();
Copy to ClipboardCopied!Toggle word wrapToggle overflow
resourceArray now contains all resources which are part of the group. Next, check if there are JBoss AS 5 Server instances which need to be restarted before the application is deployed.
for( i in resourcesArray ) {
var res = resourcesArray[i];
var resType = res.resourceType.name;
println(" Found resource " + res.name + " of type " + resType + " and ID " + res.id);
if( resType != "JBossAS5 Server") {
println(" ---> Resource not of required type. Exiting!");
usage();
}
// get server resource to start/stop it and to redeploy application
var server = ProxyFactory.getResource(res.id);
}
for( i in resourcesArray ) {
var res = resourcesArray[i];
var resType = res.resourceType.name;
println(" Found resource " + res.name + " of type " + resType + " and ID " + res.id);
if( resType != "JBossAS5 Server") {
println(" ---> Resource not of required type. Exiting!");
usage();
}
// get server resource to start/stop it and to redeploy application
var server = ProxyFactory.getResource(res.id);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
This requires a group with only JBoss AS 5 Server resource types as top level resources. Now server contains the JBoss AS 5 instance. This requires re-reading the server because it needs to be fully populated. Internally, the CLI is using simple JPA persistence, and it is necessary to not always fetch all dependent objects.
Next, traverse all the children of the server instance and find the resource name of the application:
var children = server.children;
for( c in children ) {
var child = children[c];
if( child.name == packageName ) {
}
}
var children = server.children;
for( c in children ) {
var child = children[c];
if( child.name == packageName ) {
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
packageName is the name of the application without version information and path as shown in the JBoss ON GUI as deployed applications.
Create a backup of the original version of the application:
println(" download old app to /tmp");
child.retrieveBackingContent("/tmp/" + packageName + "_" + server.name + "_old");
println(" download old app to /tmp");
child.retrieveBackingContent("/tmp/" + packageName + "_" + server.name + "_old");
Copy to ClipboardCopied!Toggle word wrapToggle overflow
A copy of the old application with the server name decoded in path is available in the /tmp/ directory.
Shut down the server and upload the new application content to the server. \
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Deploying the New Resource
At this point, existing application can be updated. The next step is to create the resource through the CLI and then deploy it to the JBoss server.
First, get the resource type for the application. This depends on several parameters:
The type of the application (e.g., WAR or EAR)
The type of the container the app needs to be deployed on (such as Tomcat or JBoss AS 5)
Note
All of the information about the resource type, such as the appType and appTypeName, is defined in the resource agent plug-in, in the rhq-plugin.xml descriptor. The attributes, configuration parameters, operations, and metrics for each default resource type are listed in the Resource Monitoring and Operations Reference.
For example:
var appType = ResourceTypeManager.getResourceTypeByNameAndPlugin( appTypeName, "JBossAS5" );
if( appType == null ) {
println(" Could not find application type. Exit.");
usage();
}
var appType = ResourceTypeManager.getResourceTypeByNameAndPlugin( appTypeName, "JBossAS5" );
if( appType == null ) {
println(" Could not find application type. Exit.");
usage();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Then get the package type of the application.
var realPackageType = ContentManager.findPackageTypes( appTypeName, "JBossAS5" );
if( realPackageType == null ) {
println(" Could not find JBoss ON's packageType. Exit.");
usage();
}
var realPackageType = ContentManager.findPackageTypes( appTypeName, "JBossAS5" );
if( realPackageType == null ) {
println(" Could not find JBoss ON's packageType. Exit.");
usage();
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Each resource in JBoss ON has some configuration parameters, including the WARs or EARs deployed on a JBoss AS 5 resource. As with the descriptive information, this is defined in the resource type's agent plug-in, in the rhq-plugin.xml descriptor. To be able to create a new resource, these parameters need to be filled in.
// create deployConfig
var deployConfig = new Configuration();
deployConfig.put( new PropertySimple("deployExploded", "false"));
deployConfig.put( new PropertySimple("deployFarmed", "false"));
// create deployConfig
var deployConfig = new Configuration();
deployConfig.put( new PropertySimple("deployExploded", "false"));
deployConfig.put( new PropertySimple("deployFarmed", "false"));
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The property names can be retrieved by calling a list of supported properties by the package type by calling this method:
var deployConfigDef = ConfigurationManager.getPackageTypeConfigurationDefinition(realPackageType.getId());
var deployConfigDef = ConfigurationManager.getPackageTypeConfigurationDefinition(realPackageType.getId());
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Provide the package bits as a byte array:
var inputStream = new java.io.FileInputStream(file);
var fileLength = file.length();
var fileBytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, fileLength);
for (numRead=0, offset=0; ((numRead >= 0) && (offset < fileBytes.length)); offset += numRead ) {
numRead = inputStream.read(fileBytes, offset, fileBytes.length - offset);
}
var inputStream = new java.io.FileInputStream(file);
var fileLength = file.length();
var fileBytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, fileLength);
for (numRead=0, offset=0; ((numRead >= 0) && (offset < fileBytes.length)); offset += numRead ) {
numRead = inputStream.read(fileBytes, offset, fileBytes.length - offset);
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Then, create the resource. The information is defined in the resource type's agent plug-in, in the rhq-plugin.xml descriptor. For example:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Make sure that the given JBoss AS 5 server instance is still running and that JBoss ON knows that it is running, or it will throw an exception saying that the JBoss ON agent is not able to upload the binary content to the server.