Finally have been able to get back on this. I have been looking at the new Deployer framework and the *-ds.xml deployer is a unique case in that it falls somewhere in the middle of an ObjectModelFactoryDeployer and a JaxpDeployer. Effectively there are two steps
1) parse the *-ds.xml
2) generate the metadata (somehow)
I have a working model of the new DsParserDeployer and the new DsDeployer. While it's not too bad, I just get the feeling that something is wrong. Don't know why, but it just seems like a lot of useless work for the following reasons:
a) The parsing
While I am no fan of JBossXB, I am equally reluctant to use straight JAXP for the otherwise mindless task of databinding. The initial implementation was written with JBossXB and I have started on a DsParser that uses straight JAXP to parse the *-ds.xml file. Neither seem ideal to me. This is just one of those tasks that I think other tools can handle better. I
b)The *-ds.xml format
While compatiblity is important, I don't see why we can't keep the XSLDeployer and with JBoss5 release a new deployment format fo MCF's...call it *-dsx.xml. We could generate a schema and get rid of stuff like arbitrary MBean definitions that make the parsing more complex that what it really needs to be. Further, with an XSD it would open up other options as to the binding rather than having to contend with a DTD that quite frankly none of us are all that dilligent in updating.
The MBean generation. This actually isn't so bad after I looked at the new stuff. However, with the *-ds.xml format there is always the MBean stuff to contend with. Clearly we are going to replace this with MC at some point, but for now, it's still annoying.
Chuck this mess. Write an XSD, lock it down and use *some* binding framework to generate the meta data and do the binding. Otherwise I don't see anyway around the ugliness that's going to be associated with either maintaining the JBossXB factory or the JAXP parsinng code. Once we start going down that path (actually have gone down it twice now) the code becomes no more maintainable that the XSL, in fact, I would argue that it's worse, solely for the fact that if a property needs to be added to the *-ds.xml file suddenly it has to chage in
1) The parser (JBossXB or JAXP)
2) The metadata
3) The JCA object itself (Pool, CM)
Use schema driven JBossXB then, with a SchemaResolverDeployer subclass as is done with the BeanDeployer. You annotate your schema to control the mapping.
Doing this would require me to actually write the MetaData classes is this correct? o, assuming that the classes had to evolve I would be required to modify both the schema and the classes as opposed to JAXB where I just have to modify the schema and use the xjc compiler.
Currently yes. I find that easier anyway. If you want to write a jaxb based parser helper be my guest. You will have to be restricted to the jaxb class support for the sake of a tool. That's not worth the trouble in my view given that the classes rarely change.
In this case unfortunately, the classes change quite a bit. Pooling parameters, tx behavior are evolving in JCA from release to release. The *-dsx.xml format would have to accomodate this. The EE descriptors of course are tied to Sun and those are somewhat static, but for JCA configurablity is key. Currently when stuff like this changes we rely on the XSL but that obviously is going to go away for JBoss5.
In reality, I plan to support a variety of parsers/binders
It's my plan to provide the metadata classes as a standalone client jar to allow for programmatic deployment and JAXB seemed to make this easier wherein I can version off the XSD rather than having to maintain the binary files in SVN.
At the very least, evolving the *-ds.xml format from the crap we have today to an actual XSD will make this easier regardless of what binding framework is in use. I think that is the real point I am trying to make.
Prototype it then. My only question would be can we develop something that the jaxws deployer could leverage for its jaxb parsing. Their usage is a pure annotation driven binding model.
Prototype is just about done. The last work involves hooking the DsDeployer into the JMX kernel where the current MBeans (ConnectionManager, Pool etc) can be generated. This actually turned out to be much easier than I originally thought it would be. That was the last real road block.
The *-dsx.xml format pretty much mimics the old format with a few exceptions. Again I want to avoid an either/or approach for this type of stuff. I think it's beneficial to have multiple paths for this type of stuff.
The old XSL deployer will still be around in the case that someone wants to use it so it's not as if we are making a complete break. Once JCA gets rewritten against the JCA 2.0 spec and the new MC stuff I anticipate the XSL deployer fading away.
I was skeptical at first, but I actually like the new deployers/deployment model. It allows for a ton of extension/plugin points that were all but impossible before.
This is actually proving to be a bit more tricky than what I had previously thought. Rather than push the envelope, I started with a JAXP compliant parser deployer (though this can be changed). The parsising of the *-ds(x).xml file is the trivial part. Generating the apprpriate MBeans is proving to be the real *catch*.
The org.jboss.resource.connectionmanager.RARDeployment, as well as all the other JCA related MBeans (JBossManagedConnectionPool, ConnectionManager etc) extend ServiceMBean support and as a result, rely on the default constructor being called.
As a result, there is no way to inject the DeploymentData into them with the org.jboss.resource.deployment.RARDeployment. Unfortunately, I have as of yet been unable to figure out how to set properties on the MBeans using the ServiceMetaData API. I can set dependencies, but what about regular attributes? The only thing I could find was the ServiceElementValueMetaData/ServiceJavaBeanValueMetaData.
Is there an API I am missing to set simple attributes on MBeans programmatically?
So, to support programmatic deployment, something has to be done. Either the existing RARDeployment has to be rewritten to extend ServiceDynamicMBeanSupport (and all the other MBeanss), or new MBeans have to be created to support this.
// set attributes List<ServiceAttributeMetaData> attrs = new ArrayList<ServiceAttributeMetaData>(); ServiceAttributeMetaData attr = new ServiceAttributeMetaData(); attr.setName("TransactionManagerFactory"); ServiceDependencyValueMetaData dependencyValue = new ServiceDependencyValueMetaData(); dependencyValue.setDependency(getTransactionManagerServiceName()); dependencyValue.setProxyType("attribute"); attr.setValue(dependencyValue); attrs.add(attr); ejbModule.setAttributes(attrs);
That's the problem. These are not dependencies, but simple attributes. If I use your approach, the Controller treats them as dependencies and won't install.
I figured out a better approach.
They don't have to be of type ServiceDependencyValueMetaData. You can just set a text value:
String value = ...; ServiceAttributeMetaData attribute = new ServiceAttributeMetaData(); attribute.setName(attributeName); attribute.setReplace(replaceAttribute); attribute.setTrim(trim); attribute.setValue(value); attributes.add(attribute);
What if it's not text? What if it's lists, collections etc.
Then that should be the value you pass to setValue.
Come again? I am not sure what you are getting at. The API provides for setting only String based attributes. Further, I tried a simple test where I set an Integer (stringified of course) attribute and it never got set appropriately.
After thinking about it, and kicking it around with other JBoss guys I have decided to add the DSXMetaData to the MetaDataRepository which now contains the ConnectorMetaData. The Repository exposes a simple MBean wrapper which allows me to establish a dependency between the old JCA MBeans to the repository iteself. As a result, the RARDeployment, JBossManagedConnectionPool etc can simply read their configuration from the respository at start.
The other way to do it would be to rework the RARDeployment, JBossManagedConnectionPool and ConnectionManager to extend the ServiceDynamicMBean. If I did this I could actually set the DSXMetaData in the constructor.