Red Hat Training

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

7.3. Breakdown of an Ant Recipe

The Ant recipe for JBoss ON bundles is the same basic file as a standard Apache Ant file and is processed by an integrated Ant build system in JBoss ON. This Ant recipe file must be bundled in the top directory of the distribution ZIP file and be named deploy.xml.
The JBoss ON Ant recipes allows all of the standard tasks that are available for Ant builds, which provides flexibility in scripting a deployment for a complex application. The JBoss ON Ant recipe must also provide additional information about the deployment that will be used by the provisioning process; this includes information about the destination and, essentially, metadata about the application itself.

Example 1. Simple Ant Recipe

For provisioning, the Ant recipe is more of a definition file than a true script file, although it can call Ant targets and do pre- and post-provisioning operations. As with other Ant scripts, the JBoss ON Ant recipe uses a standard XML file with a <project> root element and defined targets and tasks. The elements defined in the <rhq:bundle> area pass metadata to the JBoss ON provisioning system when the project is built.
The first part of the deploy.xml file simply identifies the file as an an script and references the provisioning Ant elements.
<?xml version="1.0"?>
<project name="test-bundle" default="main"
	xmlns:rhq="antlib:org.rhq.bundle">
The next element identifies the specific bundle file itself. The provisioning system can manage and deploy multiple versions of the same application; the <rhq:bundle> element contains information about the specific version of the bundle (including, naturally enough, an optional version number).
    <rhq:bundle name="Example App" version="2.4" description="an example bundle">
All that is required for a recipe is the <rhq:bundle> element that defines the name of the application. However, the bundle element contains all of the information about the application and, importantly, how the provisioning system should handle content contained in the application.
The first item to address is any templatized property that is used in a configuration file. This is covered in Section 7.5, “Using Templatized Configuration Files”. Any token used in a configuration file must be defined in the recipe for it to be realized (to have a value supplied) during provisioning. For the port token defined in Section 7.5, “Using Templatized Configuration Files”, the <rhq:input-property> element identifies it in the recipe. The name argument is the input_field value in the token, the description argument gives the field description used in the UI and the other arguments set whether the value is required, what its allowed syntax is, and any default values to supply. (This doesn't list the files which use tokens, only the tokens themselves.)
	<rhq:input-property
            name="listener.port"
            description="This is where the product will listen for incoming messages"
            required="true"
            defaultValue="8080"
            type="integer"/>
There is a single element which identifies all of the content deployed by the bundle, the <rhq:deployment-unit> element. The entire application — its name, included ZIP or JAR files, configuration files, Ant targets — are all defined in the <rhq:deployment-unit> parent element.
The name and any Ant targets are defined as arguments on <rhq:deployment-unit> directly. In this, the name is appserver, and one preinstall target and one postinstall target are set.
        <rhq:deployment-unit name="appserver" preinstallTarget="preinstall" postinstallTarget="postinstall" manageRootDir="false">
There is one other critical element on the <rhq:deployment-unit> element: the manageRootDir argument. Provisioning doesn't simply copy over files; as described in Section 2.3, “File Handling During Provisioning”, it remakes the directory to match what is in the bundle. If there are any existing files in the deployment directory when the bundle is first deployed, they are deleted by default. Setting manageRootDir to false means that the provisioning process does not manage the deployment directory — meaning any existing files are left alone when the bundle is deployed.
Any existing content in the root directory is backed up before it is deleted, so it can be restored later. The backup directory is /home/.rhqdeployments/resourceID/backup.
Any configuration file is identified in an <rhq:file> element. The name is the name of the configuration file within the bundle, while the destinationFile is the relative (to the deployment directory) path and filename of the file after it is deployed.
	<rhq:file name="test-v2.properties" destinationFile="conf/test.properties" replace="true"/>
Bundles can contain archive files, either ZIP or JAR files. Every archive file is identified in an <rhq:archive> element within the deployment-unit. The <rhq:archive> element does three things:
  • Identify the archive file by name.
  • Define how to handle the archive. Simply put, it sets whether to copy the archive over to the destination and then leave it as-is, still as an archive, or whether to extract the archive once it is deployed. This is called exploding the archive. If an archive is exploded, then a postinstall task can be called to move or edit files, as necessary.
  • Identify any files within the archive which contain tokens that need to be realized. This is a child element, <rhq:fileset>. This can use wildcards to include types of files or files within subdirectories or it can explicitly state which files to process.
            <rhq:archive name="MyApp.zip" exploded="true">
                <rhq:replace>
                    <rhq:fileset>
                        <include name="**/*.properties"/>
                    </rhq:fileset>
                </rhq:replace>
            </rhq:archive>
Another possible child element sets how to handle any files within the deployment directory that are not part of the bundle. For example, the application may generate log files or it may allow users to upload content. By default, the provisioning process cleans out a directory from non-bundle content every time a bundle is provisioned. However, logs, user-supplied data, and other types of files are data that should remain intact after provisioning. Any files or subdirectories which should be ignored by the provisioning process (and therefore preserved) are identified in the <rhq:ignore> element. In this case, any *.log files within the logs/ directory are saved.
            <rhq:ignore>
                <rhq:fileset>
                    <include name="logs/*.log"/>
                </rhq:fileset>
            </rhq:ignore>
        </rhq:deployment-unit>
    </rhq:bundle>
This only applies to upgrading a bundle, meaning after the initial deployment.
The last elements set the Ant tasks to run before or after deploying the content, as identified initially in the <rhq:deployment-unit> arguments. Most common Ant tasks are supported (as described in Section 7.4, “Using Ant Tasks”). This uses a preinstall task to print which directory the bundle is being deployed to and whether the operation was successful. The postinstall task prints a message when the deployment is complete.
<target name="main" />

    <target name="preinstall">
        <echo>Deploying Test Bundle v2.4 to ${rhq.deploy.dir}...</echo>
	<property name="preinstallTargetExecuted" value="true"/>
	<rhq:audit status="SUCCESS" action="Preinstall Notice" info="Preinstalling to ${rhq.deploy.dir}" message="Another optional message">
		Some additional, optional details regarding
		the deployment of ${rhq.deploy.dir}
	</rhq:audit>
    </target>

    <target name="postinstall">
        <echo>Done deploying Test Bundle v2.4 to ${rhq.deploy.dir}.</echo>
        <property name="postinstallTargetExecuted" value="true"/>
    </target>
</project>
Section 7.7, “A Reference of JBoss ON Ant Recipe Elements” lists the different JBoss ON elements in the Ant recipe file. For information on standard Ant tasks, see the Apache Ant documentation.