Home | About the author | Resume | << Serialize POJO to XML | Deployment of mbean separately to its interface >>
SMS Bundle - Mobile Marketing Solutions
SMS Bundle is an Australian-based service for sending marketing SMS and MMS

Using template to deploy a JBoss queue

How to deploy a queue using Velocity templating engine

Currently I am involved in a project, where I have to use Velocity template engine to deploy queues and message-driven beans to JBoss. Velocity is a template engine that can be used for many purposes, and in my case I am using it to generate XML descriptor for a JBoss queue, hence: some-queue-name-service.xml. Its a simple scripting language and the XML descriptor template looks quite similar to the resulting XML descriptor.

Why do we use a template for deployment?
Because some of our deployments occur at runtime, where properties for the queues and MDB's are generated on the fly and we need a templating engine to be able generate the deployments.

So i decided to describe a process of deploying a JBoss queue. I am hoping that I will be clear enough, since i am quite new to this my self.

The setup of my system:
/opt/mitto/jboss/server/mitto/
Root directory for my JBoss instance. (the [.])

My Velocity templates sit under the root, inside dynamic-templates directory:
./dynamic-templates/
JBoss deployment service will look under the root of my JBoss instance for the dynamic-templates directory.

JBoss deployment service depends on Velocity library (velocity.jar) that must be included under the root of:
./deploy/deployment-service.sar/
XML descriptor of JBoss deployment service (jboss-service.xml) sits under:
./deploy/deployment-service.sar/META-INF/
You can see below the jboss-service.xml:
<mbean
code="org.jboss.services.deployment.DeploymentService"
name="jboss:service=DeploymentService">
<attribute name="TemplateDir">
dynamic-templates
</attribute>
<attribute name="DeployDir">
dynamic-deploy
</attribute>
<attribute name="UndeployDir">
dynamic-undeploy
</attribute>
</mbean>
The three directories mentioned above in jboss-service.xml, sit under the root of my JBoss instance.
TemplateDir - where my deployment generation templates can be found.
UndeployDir - the generated modules go there.
DeployDir - the directory to use when I ask to deploy a generated module.

Now, inside the:
./dynamic-templates/
I have following structure:
jbossmessaging-queue/
/vm/
jbossmessaging-queue.xml.vm
template-config.xml
jbossmessaging-queue - directory that contains Velocity XML descriptor template for my queue. Also it represents the name of the deployment template that should be used, when createModule() method of deployment service will be called.

template-config.xml specifies the properties for Velocity template XML descriptor for our queue. Deployment service will be able to access those properties when rendering the Velocity template and to retrieve the values of JNDIName and QueueName properties.

Below you can see the descriptor for the template-config.xml:
<template-config
template="vm/jbossmessaging-queue.xml.vm"
extension="-service.xml">
<property-list>
<property name="QueueName"
type="java.lang.String" optional="false"/>
</property-list>
</template-config>
jbossmessaging-queue.xml.vm mentioned above, is the name of the actual Velocity template XML descriptor for the queue, which you can see below:
<?xml version="1.0" encoding="UTF-8"?>
<!--
==============================================
QueueName - $QueueName
==============================================
-->
<server>
<mbean
code="org.jboss.jms.server.destination.QueueService"
name="jboss.messaging.destination:service=Queue,
name=$QueueName" xmbean-dd="xmdesc/Queue-xmbean.xml">

<depends optional-attribute-name="ServerPeer">
jboss.messaging:service=ServerPeer</depends>
<attribute name="Clustered">true</attribute>
<depends>jboss.messaging:service=PostOffice</depends>

</mbean>
</server>
Implementation:
I created a service bean that will acquire proxies for the JBoss MainDeployerMBean and JBoss DeploymentServiceMBean. I will use JBoss deployment service to construct a queue module in the file system, and I will use JBoss main deployer to deploy the queue, by pointing it to the module in the file system. My implementation of my service bean as follows:
public class DeploymentService 
extends ServiceMBeanSupport
implements DeploymentServiceMBean {

private static final String
JBOSS_MAIN_DEPLOYER_SERVICE = "jboss.system:service=MainDeployer";
private static final String
JBOSS_DEPLOYMENT_SERVICE = "jboss:service=DeploymentService";

private MainDeployerMBean mainDeployerService = null;
private DeploymentServiceMBean jbossDeploymentService = null;

public void startService() throws Exception {

try {
//get proxy for main deployer service bean
mainDeployerService = getJBossMainDeployer();
}
catch (MBeanProxyCreationException e) {
e.printStackTrace();
}

try {

//get proxy for deployemnt service bean
jbossDeploymentService = getJBossDeploymentService();
}
catch (MBeanProxyCreationException e) {
e.printStackTrace();
}

deploy();
}

public void stopService() {

}


private void deploy() {

//hashmap contains properties for the queue template
HashMap<String, Object> properties = new HashMap<String, Object>();

//short file name of my queue
String destination = "myqueue-service.xml";


//directory name where the queue Velocity template is kept,
//inside 'dynamic-templates' dir
String template = "jbossmessaging-queue";


//property that holds a queue name for the Velocity template
properties.put("QueueName", "myqueue");


String resultingFileName = "";

//create a queue module in a filesystem, at this stage queue
//is not deployed yet.
try {
resultingFileName = jbossDeploymentService
.createModule(destination, template, properties);
} catch (Exception e) {
e.printStackTrace();
}

String path = constructPath(destination);

try {
//check whether deployment exists for the given
//module queue in the file system
if (!mainDeployerService.isDeployed(path)) {

mainDeployerService.deploy(path);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}

}

//construct an absolute path to the queue module in a filesystem
//for a given name.
private String constructPath(String shortName) {
String path = ServerConfigLocator.locate().getServerHomeDir()
.getAbsolutePath()
+ "/"
+ jbossDeploymentService.getUndeployDir()
+ "/"
+ shortName;
return path;
}

//Constructs and returns a proxy for MainDeployerMBean
private MainDeployerMBean getJBossMainDeployer()
throws MBeanProxyCreationException
{
MBeanServer server = getServer();

ObjectName serviceName = new ObjectName(JBOSS_MAIN_DEPLOYER_SERVICE);

//'false' -> dont make the returned proxy implement NotificationEmitter interface
MainDeployerMBean mainDeployer =
(MainDeployerMBean) MBeanServerInvocationHandler
.newProxyInstance(server, serviceName,
MainDeployerMBean.class, false);

return mainDeployer;
}


//Constructs and returns a proxy for DeploymentServiceMBean
private DeploymentServiceMBean getJBossDeploymentService()
throws MBeanProxyCreationException
{
MBeanServer server = getServer();

ObjectName serviceName = new ObjectName(JBOSS_DEPLOYMENT_SERVICE);

//'false' -> dont make the returned proxy implement NotificationEmitter interface
DeploymentServiceMBean deploymentService =
(DeploymentServiceMBean) MBeanServerInvocationHandler
.newProxyInstance(server, serviceName,
DeploymentServiceMBean.class, false);

return deploymentService;
}

}
Two main points that i want to explain here are:
createModule() method of JBoss deployment service and
deploy() of JBoss main deployer.

createModule() - accepts three arguments: resulting file name (in this case is myqueue-service.xml), the directory name where the Velocity template is kept and a HashMap object which contains properties for the template.

JBoss deployment service will use the Velocity template to generate myqueue-service.xml module under dynamic-undeploy directory.

deploy() - accepts a path to the module in the system and deploys the module. In this case the path to the module is:
/opt/mitto/jboss/server/mitto/
dynamic-undeploy/myqueue-service.xml
Thats about it :) You can use Velocity templates to deploy queues, message-driven and other types of beans. Basically anything that has XML descriptors.
I really hope I was clear enough in this example, since it is quite consized.
Categories : jboss, velocity, queues, xml, jms
Technorati Tags : , , , , , ,
Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Related Posts
JBoss Security - JMX Console
Hibernate Event Interceptor
Drools - tutorial on writing DSL template
Drools - Stop executing current agenda group and all rules
Deployment of mbean separately to its interface
Bitwise operation in Hibernate 3
JBoss Clustering - HASingleton service
Drools - working with Stateless session




If you like this post, then consider subscribing to the full feed RSS.



Re: Using template to deploy a JBoss queue

Hi, great job! Sorry for my english, I speak spanish. How do you deploy programatically the MDBs? In my application, i have one  fixed queue , but I need to deploy MDBs at runtime.  Thanks

Re: Using template to deploy a JBoss queue

Hola amigo!, yes you can deploy MDB programmatically. You can create Velocity template which you will use to generate module with ejb-jar.xml and jboss.xml inside, to imitate EJB JAR. You can create collection of properties that normally MDB has in its ejb-jar.xml and jboss.xml, and use them to create deployment module in the file system.

Now, the created module will be a directory with extension .JAR.

Something like my-mdb.jar which is actualy a directory where ejb.jar.xml and jboss.xml will be sitting inside META-INF. JBoss will think that it is actual archive.

Please note:
You will also need to have MDB class already deployed in the system. It needs to be loaded before you point JBoss's main deployer to the module you created.

In ejb-jar.xml, you specify that class name inside <ejb-class> element <ejb-class>com.sample.EmailMDB</ejb-class>

The class name can be set as one of the properties needed for Velocity template.

Once you generated the above, you can point JBoss's main deployer to the module by calling deploy().
I hope i was clear enough for you here. Cheers

Re: Using template to deploy a JBoss queue

Update:
I found today this post of some person that describes how to use Velocity in Spring applications. (I don't know that person's name). Worth while to have a read.

Re: Using template to deploy a JBoss queue

Alexander,

Nice writeup and interesting approach. Thanks for stopping by my blog.

Charles aka "Heuristic Exception"

Add a comment    Send a TrackBack