5.11.2. Mbean deployments using HASingletonController

5.11.2. Mbean deployments using HASingletonController

If your service is an Mbean (i.e., not a J2EE deployment like an ear or war or jar), you can deploy it along with a service called an HASingletonController in order to turn it into an HA singleton. It is the job of the HASingletonController to work with the HAPartition service to monitor the cluster and determine if it is now the master node for its service. If it determines it has become the master node, it invokes a method on your service telling it to begin providing service. If it determines it is no longer the master node, it invokes a method on your service telling it to stop providing service. Let's walk through an illustration.

First, we have an MBean service that we want to make an HA singleton. The only thing special about it is it needs to expose in its MBean interface a method that can be called when it should begin providing service, and another that can be called when it should stop providing service:

 
public class HASingletonExample
implements HASingletonExampleMBean { 
 
private boolean isMasterNode = false; 
  
public void startSingleton() { 
isMasterNode = true; 
} 
. 
public boolean isMasterNode() { 
return isMasterNode; 
 } 
  
 public void stopSingleton() { 
 isMasterNode = false; 
 } 
}  

We used “startSingleton” and “stopSingleton” in the above example, but you could name the methods anything.

Next, we deploy our service, along with an HASingletonController to control it, most likely packaged in a .sar file, with the following META-INF/jboss-service.xml:

 <server> 
	 <!-- This MBean is an example of a clustered singleton --> 
	 <mbean code="org.jboss.ha.examples.HASingletonExample" 
		name=“jboss:service=HASingletonExample"/> 
	 
	 <!-- This HASingletonController manages the cluster Singleton --> 
	 <mbean code="org.jboss.ha.singleton.HASingletonController" 
		name="jboss:service=ExampleHASingletonController"> 
		 
		 <!-- Inject a ref to the HAPartition -->
		 <depends optional-attribute-name="ClusterPartition" proxy-type="attribute">
			 jboss:service=${jboss.partition.name:DefaultPartition}
		 </depends>  
		 <!-- Inject a ref to the service being controlled -->
		 <depends optional-attribute-name="TargetName">
			 jboss:service=HASingletonExample
		 </depends>
		 <!-- Methods to invoke when become master / stop being master -->
		 <attribute name="TargetStartMethod">startSingleton</attribute> 
		 <attribute name="TargetStopMethod">stopSingleton</attribute> 
	 </mbean> 
</server> 

Voila! A clustered singleton service.

The obvious downside to this approach is it only works for MBeans. Upsides are that the above example can be placed in deploy or farm and thus can be hot deployed and farmed deployed. Also, if our example service had complex, time-consuming startup requirements, those could potentially be implemented in create() or start() methods. JBoss will invoke create() and start() as soon as the service is deployed; it doesn't wait until the node becomes the master node. So, the service could be primed and ready to go, just waiting for the controller to implement startSingleton() at which point it can immediately provide service.

The jboss.ha:service=HASingletonDeployer service discussed above is itself an interesting example of using an HASingletonController. Here is its deployment descriptor (extracted from the deploy/deploy-hasingleton-service.xml file):

 
<mbean code="org.jboss.ha.singleton.HASingletonController" 
name="jboss.ha:service=HASingletonDeployer"> 
 <depends optional-attribute-name="ClusterPartition" proxy-type="attribute">
  jboss:service=${jboss.partition.name:DefaultPartition}
 </depends>  
 <depends optional-attributeame="TargetName">
  jboss.system:service=MainDeployer
 </depends> 
 <attribute name="TargetStartMethod">deploy</attribute> 
 <attribute name="TargetStartMethodArgument">
  ${jboss.server.home.url}/deploy-hasingleton
 </attribute> 
 <attribute name="TargetStopMethod">undeploy</attribute> 
 <attribute name="TargetStopMethodArgument">
  ${jboss.server.home.url}/deploy-hasingleton
 </attribute> 
</mbean> 

A few interesting things here. First the service being controlled is the MainDeployer service, which is the core deployment service in JBoss. That is, it's a service that wasn't written with an intent that it be controlled by an HASingletonController. But it still works! Second, the target start and stop methods are “deploy” and “undeploy”. No requirement that they have particular names, or even that they logically have “start” and “stop” functionality. Here the functionality of the invoked methods is more like “do” and “undo”. Finally, note the “TargetStart(Stop)MethodArgument” attributes. Your singleton service's start/stop methods can take an argument, in this case the location of the directory the MainDeployer should deploy/undeploy.