4. Example: Deploying an Application with Bundles (JBoss EAP 4, 5, and 6)

Bundles are a very clean and easy way to deploy updated applications to JBoss EAP 6 servers. The bundles system maintains multiple versions of a given package and can deploy any of those versions to a specified compatible group. This is a great workflow for application lifecycles, since a stable version can be deployed to production servers while a development version can be deployed to test machines.
The deploy-to-and-restart-JBAS.js script in the cliRoot/rhq-remoting-cli-3.1.2.GA/samples directory defines a set of custom functions that quickly create a bundle version and definition and then deploy it to the given JBoss servers.

4.1. Creating a New Application

The deploy-to-and-restart-JBAS.js script requires the util.js and bundles.js scripts for supporting functions. This is easiest to do when running the CLI interactively, because all of the scripts can be loaded using the exec command.
[root@server bin]# ./rhq-cli.sh -u rhqadmin -p rhqadmin
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/util.js
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/bundles.js
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/deploy-to-and-restart-JBAS.js
The deploy-to-and-restart-JBAS.js script defines a function called createAppAndRestartJBAS that creates and then deploys a bundle. The function takes seven parameters:
  • The path to the bundle archive file.
  • A configuration object that contains any tokens or variables required for the bundle configuration. In this example, no properties are passed, so the value is null. Details about the configuration are in the comments in the bundles.js file and general configuration information is in Section 6.2, “Changing Simple Configuration Properties”.
  • The name of the compatible group to which to deploy the bundle.
  • A name of the bundle destination.
  • A description for the bundle destination.
  • The base directory to which to deploy the bundle and, optionally, a subdirectory to deploy the bundle to.
For example:
rhqadmin@localhost:7080$ var bundleZipFile = /export/bundles/myBundle.zip 
rhqadmin@localhost:7080$ var deploymentConfiguration = null
rhqadmin@localhost:7080$ var groupName = "JBoss EAP 6 Group"
rhqadmin@localhost:7080$ var destinationName = "My App - JBoss EAP 6 Destination"
rhqadmin@localhost:7080$ var destinationDescription = "For my application"
rhqadmin@localhost:7080$ var baseDirName = "Install Directory"
rhqadmin@localhost:7080$ var deployDir = "deploy"
rhqadmin@localhost:7080$ createAppAndRestartJBAS(bundleZipFile, deploymentConfiguration, groupName, destinationName, destinationDescription, baseDirName, deployDir)
There are a number of private functions defined in the deploy-to-and-restart-JBAS.js script which provide support to the createAppAndRestartJBAS function. Those are explained in the comments in the deploy-to-and-restart-JBAS.js file.

NOTE

The baseDirName variable must have a value of Install Directory or Profile Directory. Those two locations are then identified based on the connection information for the specified JBoss EAP resource which is accessed by the script.
The createAppAndRestartJBAS function has three parts: finding the resource group, creating the bundle, and restarting the JBoss servers in the group.
The first part searches for the specific group by the given group name, and it must match only a single resource group. Otherwise, it returns an error.
function createAppAndRestartJBAS(bundleZipFile, deploymentConfiguration, groupName, destinationName, destinationDescription, baseDirName, deployDir) {
    var gcrit = new ResourceGroupCriteria;
    gcrit.addFilterName(groupName);
    gcrit.fetchResourceType(true);

    var groups = ResourceGroupManager.findResourceGroupsByCriteria(gcrit);
    if (groups.empty) {
        throw "Could not find a resource group called " + groupName;
    } else if (groups.size() > 1) {
        throw "There are more than 1 groups called " + groupName;
    }

    var group = groups.get(0);
    var targetResourceType = group.resourceType;
Part of the search instruction is to fetch the resource type for the given compatible group. That resource type is then used to create the bundle destination, which is associated with a group.
The next part creates the bundle and restarts the server resources.
    var deployFn = function(restartFn) {
The first part of create a bundle deployment is uploading the bundle archive to create a bundle version in the JBoss ON configuration.
        var bundleVersion = createBundleVersion(bundleZipFile);
Next, it creates the destination, which is the definition of where the bundle is to be deployed (the base and deployment directories), associated with a compatible group and with the bundle version.
        var destination = BundleManager.createBundleDestination(bundleVersion.bundle.id, destinationName, destinationDescription, baseDirName, deployDir, group.id);
Once the destination and the version are defined, then they can be saved and deployed to the target resource group.
        var deployment = deployBundle(destination,bundleVersion, deploymentConfiguration, "Web application", false);

        if (deployment.status != BundleDeploymentStatus.SUCCESS) {
            throw "Deployment wasn't successful: " + deployment;
        }
When the deployment completes, then the script iterates through the group members (defined in one of the help functions in the deploy-to-and-restart-JBAS.js script) and restarts each resource. It then prints the deployment information.
        restartFn(group);

        return deployment;
    };
The deploy-to-and-restart-JBAS.js script can deploy content to any supported version of JBoss EAP: 4, 5, or 6. The bundle system uses the configuration defined in the resource plug-in, based on the resource type of the group. For the restart operation, different restart function are defined for each version of JBoss EAP.
    if (targetResourceType.plugin == "JBossAS" && targetResourceType.name == "JBossAS Server") {
        return deployFn(_restartAS4);
    } else if (targetResourceType.plugin == "JBossAS5" && targetResourceType.name == "JBossAS Server") {
        return deployFn(_restartAS5);
    } else if (targetResourceType.plugin == "JBossAS7" &&
            (targetResourceType.name == "JBossAS7 Standalone Server" ||
                    targetResourceType.name == "JBossAS-Managed")) {
        return deployFn(_restartAS7);
    }

    throw "The resource group the destination targets doesn't seem to be a JBoss AS server group.";
}

4.2. Updating Applications

Updating an application is simpler than creating one because the bundle definition already exists.
As with creating a new application, all three scripts — util.js, bundles.js, and deploy-to-and-restart-JBAS.js — need to be loaded using the exec command.
[root@server bin]# ./rhq-cli.sh -u rhqadmin -p rhqadmin
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/util.js
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/bundles.js
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/deploy-to-and-restart-JBAS.js
To update an application, give the path to the updated bundle archive, any tokens or properties to set, and the existing bundle destination.
rhqadmin@localhost:7080$ var bundleZipFile = /export/bundles/myBundle.zip 
rhqadmin@localhost:7080$ var deploymentConfiguration = null
rhqadmin@localhost:7080$ var jbasDestination = "My App - JBoss EAP 6 Destination"
rhqadmin@localhost:7080$ updateAppAndRestartJBAS(bundleZipFile, jbasDestination, deploymentConfiguration)
If the bundle requires any tokens to be realized, like a port number to be entered, then you must create a configuration object and pass the values to that. In this example, no properties are passed, so the value is null. Details about the configuration are in the comments in the bundles.js file and general configuration information is in Section 6.2, “Changing Simple Configuration Properties”.
The destination identifier — which could be the destination name or the ID — is used in a criteria search to fetch the resource type for the compatible group. This, as with the create function, identifies which version of JBoss EAP is being used.
function updateAppAndRestartJBAS(bundleZipFile, jbasDestination, deploymentConfiguration) {
    // first figure out the jbas version we are deploying to
    var destinationId = jbasDestination;
    if (typeof(jbasDestination) == 'object') {
        destinationId = jbasDestination.id;
    }

    var destCrit = new BundleDestinationCriteria
    destCrit.fetchGroup(true)
It uses the name to search for the destination ID. When it retrieves the destination entry (in the get(0) call), the destination configuration contains the resource type.
    var destinations = BundleManager.findBundleDestinationsByCriteria(destCrit);

    if (destinations.empty) {
        throw "No destinations corresponding to " + jbasDestination + " found on the server.";
    }

    var destination = destinations.get(0);

    var targetResourceType = destination.group.resourceType;

    if (targetResourceType == null) {
        throw "This function expects a compatible group of JBoss AS (4,5,6 or 7) resources but the provided destination is connected with " + destination.group;
    }
Then, it uploads the new bundle archive as a new bundle version, in the createBundleVersion method.
    var deployFn = function(restartFn) {
	var bundleVersion = createBundleVersion(bundleZipFile);
Then, it deploys the new bundle version to the existing destination, along with any defined or required tokens in a configuration object (deploymentConfiguration). When the deployment completes, it restarts the JBoss resources in the group and prints the deployment information.
        var deployment = deployBundle(destination,bundleVersion, deploymentConfiguration, "Web application", false);

        if (deployment.status != BundleDeploymentStatus.SUCCESS) {
            throw "Deployment wasn't successful: " + deployment;
        }

        restartFn(destination.group);

        return deployment;
    };
As with the creation function, there are version-specific restart methods for any supported version of JBoss EAP: 4, 5, or 6. The bundle system uses the configuration defined in the resource plug-in, based on the resource type of the group.
    if (targetResourceType.plugin == "JBossAS" && targetResourceType.name == "JBossAS Server") {
        return deployFn(_restartAS4);
    } else if (targetResourceType.plugin == "JBossAS5" && targetResourceType.name == "JBossAS Server") {
        return deployFn(_restartAS5);
    } else if (targetResourceType.plugin == "JBossAS7" &&
            (targetResourceType.name == "JBossAS7 Standalone Server" ||
                    targetResourceType.name == "JBossAS-Managed")) {
        return deployFn(_restartAS7);
    }

    throw "The resource group the destination targets doesn't seem to be a JBoss AS server group.";
}