The Deployment Service is an experimental feature of JBoss v3.2.7/v4.0.1,
currently located at docs\examples\varia\deployment-service (see readme.txt
for installation instructions).
It serves the purpose of creating and managing new deployment modules
(e.g. .sar) consisting of one or more deployment descriptors and possibly
other files (e.g. jars). It can be thought of as a proxy that acts on
behalf of the administrator that can create and deploy new descriptors
in the well known JBoss ./deploy directory.
There are 2 expected usages of the Deployment Service:
Allow application code to create MBean services (either JBoss ones or
provided by the user) that are durable, i.e. they survive a
server re-start. For example, it is currently possible
to instantiate a new JMS queue using the management interface of the
jboss.mq:service=DestinationManager MBean, however, the queue will
be gone if the server restarts.
Allow an administrator to generate and manage deployments
through management tools. By using metadata provided by the
Deployment Service, it may even be possible to achieve some
degree of generic behaviour (more about this, later).
The deployment service is an MBean itself configured by the
deployment descriptor. It's main dependency is on the apache
a popular Java-based template engine, used here for
generating deployment descriptors.
There are 3 directories of interest that can be configured:
TemplateDir - points to the directory where deployment generation
templates/config files may be found, by default ./conf/templates.
UndeployDir - the directory to use when generating deployments,
by default ./undeploy
DeployDir - the directory to use when requested to deploy
a generated module, by default ./deploy
Upon start-up the DeploymentService creates DeployDir and UndeployDir
if they don't exist, and then scans the TemplateDir for all
immediate subdirectories that contain a file named template-config.xml.
Each of those files describes a particular template configuration that can
produce deployments of a particular type. Those files are then parsed
and loaded in memory. The name of the subdirectory gives the name to each
particular deployment template, for example,
templates/jms-queue/template-config.xml yield the name jms-queue.
The service (currently) does not hold any other state.
How it Works
To understand the way the DeploymentService works we will
walk through its exposed JMX operation API.
listModuleTemplate() - returns a java.util.Set containing the String names
of all deployment templates found. Those template names can be used in the
getTemplatePropertyInfo() and createModule() operation.
getTemplatePropertyInfo(String template) - returns a java.util.List object
containing org.jboss.services.deployment.metadata.PropertyInfo instances.
Each deployment template describes a list of properties supported
(or required) by that particular template. For example, the jms-queue
requires a QueueName to be supplied as input. It also specifies
the type of the property (e.g. java.lang.String) along with an optional
free-text description and a possible default-value.
createModule() - this is a factory method. It requires 3 arguments,
an arbitrary module name to be produced (e.g. myModule), the name of
the deployment template to use (e.g. jms-queue) and finally a HashMap
containing the properties required by that particular template.
Depending on the deployment template, the end result will be either
a single deployment descriptor (e.g. myModule-service.xml), or a
directory name (e.g. myModule.sar) containing the generated files.
Since the deployment template can alter the suffix of the produced
module (e.g. adding a -service.xml to the supplied value, if it is not
already there), the final module name is the return value of the method.
The generated descriptor/directory is output to the UndeployDir.
In case of an error, an exception is thrown and any intermediate
results are removed.
deployModuleAsynch() - it accepts a module name as a parameter
(e.g. myModule-service.xml) and tries to move the specified
file or directory from UndeployDir to DeployDir, then
returns immediately. Assuming that DeployDir is scanned by
a deployment scanner, the module will be deployed.
getDeployedURL() - returns a URL that points to the module in the
DeployDir. This can be used, for example, to query the MainDeployer
and find out about the fate of the deployment (started/failed/etc.).
undeployModuleAsynch() - the opposite of deployModuleAsynch()
moves back the module to UndeployDir so it will be evendually
getUndeployedURL() - returns a URL that points to the module in the
UndeployDir. This could be used, for example, if someone wants to
deploy the module within UndeployDir directly with the MainDeployer,
thus, avoiding moving the module to DeployDir and getting more immediate
feedback. In this case, however, the module will not be automatically
deployed upon a server restart.
removeModule() - remove the specified module from UndeployDir.
Example - creating a JMS Queue
If you know/control a particular deployment template and its properties,
it is relatively straightforward to use it in order to create deployable
modules. Taking the example deployment template defined in
conf/templates/jms-queue/template-config.xml, we can see that the only
required property (without a default value) is the QueueName of type
java.lang.String. The code to create and deploy a new Queue named "Q"
would look as follows:
import javax.management.MBeanServer; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectName; import org.jboss.mx.util.MBeanServerLocator; import org.jboss.services.deployment.DeploymentServiceMBean; ... // find the local MBeanServer MBeanServer server = MBeanServerLocator.locateJBoss(); // target MBean ObjectName objectName = new ObjectName("jboss:service=DeploymentService"); // Get a type-safe dynamic proxy DeploymentServiceMBean dservice = (DeploymentServiceMBean)MBeanServerInvocationHandler.newProxyInstance( server, objectName, DeploymentServiceMBean.class, false); // Prepare the properties HashMap properties = new HashMap(); map.put("QueueName", "Q"); String module = dservice.createModule("myqueue", "jms-queue", properties); dservice.deployModuleAsynch(module); ... // call getDeployment(dservice.getDeployedURL(module)); // on MainDeployer to get the describing DeploymentInfo // for the deployment.
A quick&dirty way to test simple deployment templates is to
call through the jmx-console the second createModule() method that
takes as input a String array as it's 3rd parameters. In the previous
example, you'd have to supply the values:
myqueue jms-queue QueueName=Q
Then see the deployment descriptor myqueue-service.xml produced in the
./undeploy directory. It should be something similar to:
<?xml version="1.0" encoding="UTF-8"?> <!-- Automatically generated by DeploymentService =================================================================== QueueName - Q DestinationManager - jboss.mq:service=DestinationManager SecurityManager - $SecurityManager SecurityRoles - $SecurityRoles =================================================================== --> <server> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=Q"> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> </mbean> </server>
Then call deployModuleAsynch() passing as a parameter the module name
myqueue-service.xml, to deploy your module.
Writing your own deployment templates
See the WritingDeploymentTemplates page.