The simplejms demo demonstrates the usage of publishing to a JMS and receiving from a JMS destination.
The demo uses the more modern approach to deploy a channel as a JBoss service.Here is the jboss-service.xml
The deployment descriptor is an ordinary jboss service xml file, and it is possible to use all the features supported by jboss. We begin by defining a local-directory, which means that JBoss will automatically create that directory under its data directory the first time the channel is deployed and populate it with data under that path from the sar-file
<local-directory path="channels/simplejms/"/>
In the channel/application we have defines two services. The first one is a GET service, which fetches files from a directory and publish the data to a JMS channel. The second one is a REC channel that receives messages through a JMS listener, namely a message driven bean.
For the GET channel we have defines a ContentMapEntry that has an url of ".", which means that its protocol handler should fetch files directly under its specified URL:
<content-map>
<content-map-entry name="jmsin">
<url>.</url>
<mime>text/xml</mime>
<protocol>DIR</protocol>
<root-element></root-element>
</content-map-entry>
</content-map>
In the next section we define a directory protocol handler. It will look for files at its BaseUrl. Here we also use a System property set by JBoss to locate its data directory. As we can see it will fetch files from the directory channels/simplejms/data/. Put any file in there when the channel is deployed and it will be picked up.
<protocol-factory
className="org.backsource.amsterdam.service.protocol.DefaultProtocolFactory">
<protocol-handler-factory
className="org.backsource.amsterdam.plugins.file.DirProtocolHandlerFactory">
<protocol-conf>
<conf name="BaseUrl">${jboss.server.data.dir}/channels/simplejms/data/</conf>
</protocol-conf>
</protocol-handler-factory>
</protocol-factory>
All GET invokers must have a cron job. This is a scheduler that will start the protocol handler at the specified interval. The syntax much like ordinary crontab. The nameref of the crontab entry must point to a valid ContentMapEntry.
<cron>
<cron-entry>
<schedule-at>* * * * *</schedule-at>
<job nameref="jmsin"/>
</cron-entry>
</cron>
Next comes just a debugging filter, and we finish with a publisher that publish to the JMS destination topic/testTopic.
<publisher
className="org.backsource.amsterdam.plugins.jms.SimpleJMSPublisher">
<jms-factory-jndi>java:/ConnectionFactory</jms-factory-jndi>
<jms-dest-type>javax.jms.Topic</jms-dest-type>
<jms-dest-jndi>topic/testTopic</jms-dest-jndi>
</publisher>
Service number two is a little more complicated. To receive messages from a JMS destination it uses two external components.
Firstly it uses what could be called an external protocol adapter.When using the org.backsource.amsterdam.service.jboss.RecMBeanServiceInvoker REC service invoker, its possible to tell it to register itself in an already available MBean (a Channel MBean). We can see how this is done:
<rec-service-invoker
className="org.backsource.amsterdam.service.jboss.RecMBeanServiceInvoker"
name="amsterdam.channel:service=Service,name=jmsout"
use-bean="true"
/>
You can also see how simple this amsterdam conf looks, since no ContentMap is created (a default entry with the same name as the service is created for REC services) and that there are no protocol factories and such. Simply put: the invoker will register a handle with the external bean through which it can invoke the service.
This external bean is registered earlier in the jboss-service file:
<mbean code="org.backsource.amsterdam.plugins.jms.JmsChannel"
name="amsterdam.channel:service=Service,name=jmsout">
<depends>amsterdam:service=AmsterdamChannel,name=simplejms</depends>
<attribute name="JNDIName">amsterdam/jmsChannel</attribute>
</mbean>
There are two important things to note here:
Secondly it uses a the org.backsource.amsterdam.plugins.jms.ProtocolListenerBean from the plugin package, see its javadoc. It must be packed as a EJB file. This ejb-jar must be correctly configured. Its resource reference jmx/JmsChannel must point to the JNDI name specifyed above. Here is how it may look in the jboss.xml
<message-driven>
<ejb-name>ProtocolListener</ejb-name>
<destination-jndi-name>topic/testTopic</destination-jndi-name>
<resource-ref>
<res-ref-name>jmx/JmsChannel</res-ref-name>
<jndi-name>amsterdam/jmsChannel</jndi-name>
</resource-ref>
</message-driven>
In a more modern JBoss its also a good idea to define a depends element in jboss.xml. This element should point to the object name of the external channel bean:amsterdam.channel:service=Service,name=jmsout. The ejb jar-file is packed inside the sar that makes up the simplejms channel.