Monday, July 30, 2007

Utilizing Installation Descriptor Extensions in JBI

JBI provides a means to add extensions to your Installation Descriptor (jbi.xml). These extensions can be used for a variety of different things, like configuration for your component. Working examples of components utilizing this feature check out the OpenESB HTTP Binding Component or ServiceMix HTTP Binding Component . Recently I needed to use this feature to add some configuration type attributes to the component we were developing. The first thing you will need to do is add the extensions to your installation descriptor. As noted in the API, the Installation Descriptor Extensions are located at the end of the <component> element of the installation descriptor, something like the following:


<component>
....
The rest of the jbi.xml
....
<config:Configuration>
<config:Port>8888</config:Port>
<config:Location>localhost</config:Location>
</config:Configuration>
</component>


During bootstrap init() the InstallationContext is passed in, this object gives you access to the Installation Descriptor Extensions, via installationContext.getInstallationDescriptorExtensions (Which returns a DocumentFramgment containing all Extensions). At this time you need to store the values in an object so that you can access them during the Components init(). The best way to achieve this is to use JMX. So the first thing you will need to do is Create an Interface that defines your MBean, and then create your class that will implement that interface. Something like the following:

public interface ConfigExtensionsMBean {
public void parseConfigExtensions(DocumentFragment documentFragment);
public String getLocation();
public int getPort();
}
Now we need to write our concrete class that implements this interface, something like the following:

public class ConfigExtensions implements ConfigExtensionsMBean {

private int port;
private String location;

public enum Attributes {Location, Port};

public String getLocation() {
return location;
}

private void setLocation(String location) {
this.location = location;
}

public int getPort() {
return port;
}

private void setPort(String port) {
this.port = new Integer(port);
}

public void parseConfigExtensions(DocumentFragment frag) {
//Parse the DocFrag here and call the setters for the port and location.
}
}
So now we have the Interface and the Concrete class, we just have to use it now. So the first thing we need to do is in your Bootstrap classes init() method we need to get the Installations Service Description Extensions and create our MBean and register that MBean in our MBean server, this should look something like the following:

public void init(InstallationContext context) {
ConfigExtensionsMBean mBean = new ConfigExtensions();
DocumentFragment doc = context.getInstallationDescriptorExtension();
mBean.parseConfigExtensions(doc);

MBeanServer mBeanServer = context.getContext().getMBeanServer();
ObjectName mBeanName = context.getContext().getMBeanNames().createCustomComponentMBeanName("MyMBean");
try {
if (!mBeanServer.isRegistered(mBeanName) {
ObjectInstance oi = mBeanServer.registerMBean(mBean, mBeanName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
So what we just did was read the extensions, parse them and call the setters, and registered the mBean for future use. So now our new component is ready to be initialized and needs access to that mBean. The following is how you can access them during ComponentLifeCycle.init(ComponentContext context):

public void init(ComponentContext context) {
MBeanServer mBeanServer = context.getMBeanServer();
ObjectName mBeanName = context.getMBeanNames()
.createCustomComponentMBeanName("MyMBean");

try {
host = (String) mBeanServer.getAttribute(mBeanName,
ConfigExtensions.Attributes.Location.toString());
port = (Integer) mBeanServer.getAttribute(mBeanName,
ConfigExtensions.Attributes.Port.toString());
} catch (Exception e) {
log.warning("Exception getting mBean Attributes: " + e);
e.printStackTrace();
}
}
So, there you have it, an example of how to utilize the Installation Descriptor Extensions from your jbi.xml.

No comments: