EBWS service has a standard (non configurable) gateway. If you use a jms-jca-provider (transacted = true) and a jms-listener within your EBWS service (webservice=true) you have already the JMS functionality. You do need to make your JBossMessaging persistend to something other then the standard Hypersonic (in memory) database.
Hi Hans and thanks for your answer but could you please explain in more detail?
If you have an JBossESB service you have the possibility to define 2 kinds of listeners: ESB-aware and ESB-unaware (also known as gateways). The gateway puts the message from an ESB unaware source onto the bus, which means the ESB-aware listener will pickup this message.
For EBWS there is a standard HTTP-gateway defined so you need not to bother with that. If you want performance and don't care about any message loss (which can be the case e.g. when doing synchronous communication) you can set invmScope="GLOBAL" (in memory queue) on your service. You do not need to add a specific listener when the INVM-scope is set. If you want quality of service, you need to persist your messages in a queue. By defining a JMS-listener (and counterpart jms-provider) you will enable an ESB-aware listener for your service. This means the gateway will passthrough your message to your JMS-queue.
Please read the programmers guide for more information on this topic.Also looking at the quickstarts will help with any configuration issues.
Thanks for the explanation,
I was testing with a single EBWS service which had two JMS listeners (one gateway and one ESB-aware) listening for channels defined within a JCA Provider (jms-jca-provider) but the message wasn’t redelivered when an exception occurred. After reading your comment, I detected that invmScope of my service was set to GLOBAL and after changing this the messages was redelivered when exception occurred.
An EBWS service automatically uses an ESB-unaware listener (HTTP-gateway as you mentioned) and no such listener is needed to be specified on the service. If invmScope is set to GLOBAL, no ESB-aware listener is needed to be specified either (and existing specified ESB-aware listeners are not used) since this is also handled automatically. Have I understood this correctly?
By the way, I know that it is possible to set the maximum number of times a message is redeliveries before it is sent to the DLQ (by setting dLQMaxResent in jboss-esb.xml). Is it somehow possible to set the interval between the redelivery attempts and/or an alternative for sending the message to the DLQ?
Yes, you have understood it correctly.
If you are talking about using dLQMaxResent in your activation config, then don't. This is because of a bug in JBossESB: messages will be redelivered by JMS aswell as by the messagestore of JBossESB. So that means 2 messages redeliverd instead of the one original message.
I would suggest you put this code in to prevent this from happening:
<activation-config><!-- Bugfix for preventing duplicate redelivery -->/>
This deactivates the redelivery from JMS, so you don't have the dubble redelivery.
Furthermore you have to look at the jboss-xml in jbossesb-server-4.9\server\default\deploy\jbossesb.esb\META-INF\jboss-esb.xml.
There you will find :
<service category="JBossESB-Internal" name="RedeliverService" description="Scheduled Service to Redeliver Messages">
<!-- add transacted="true" attribute to enable transacted redelivery -->
<scheduled-listener name="redeliver-scheduled-listener" scheduleidref="5-min-trigger"
<action name="RedeliverMessagesAction" class="org.jboss.soa.esb.actions.MessageRedeliverer">
<property name="max-redeliveries" value="20"/>
Changing the max-redeliveries here will change your redelivery behavior. Also the provider for the scheduler (see the scheduleref) contains the possibility to change the time (in milliseconds) which will be used to wait for redelivery.
I haven't set the useDLQ property at all but I don't seem to get duplicated redeliveries. I have set DLQMaxResent to 3 and the message is redelivered 3 times before beeing sent to the DLQ.
I have tested to use DLQJNDIName (property within activation-config of my JCA provider) to send the message to a specific service once the maximum number of redelivery attempts has been reached. This seems to work as it should (the message reaches the specified service) but if I redeploy the JMS enabled service (the one to which the redelivery attempts was being made) new redeliveries are made to that service. Do you know if the message is sent to DLQ even if DLQJNDIName is set to something else? Does this behavior have something to do with the bug mentioned by you or is it an expected behavior?
Forgot to add this in my last post:
The solution you suggest would mean that the redelivery functionality (including max redelivery attempts and interval) would have to be the same for all service. It wouldn't be possible to use different max redelivery attempts and intervals for different services. Correct me if I am wrong.
When I tested to set useDLQ to false, there was only 10 quick redeliveries of the message. (By quick I mean that the redeliveries were performed as fast as possible with no delay between.) According to your last post where you mentioned the "deploy\jbossesb.esb\META-INF\jboss-esb.xml" file, I expected the messages to be redelivered every fifth minute until 20 redeliveries had been made.
I haven't tried DLQJNDIName because the messages that are in my ESB are never supposed to reach the DLQ. If a message is send to a DLQ it supposed to be never to be redelivered. Why you still have redelivery I don't know, but I would like to know if you can find out if the message is in the JMS tables or in the messagestore MESSAGE table when you shut down your application server. If it's in the MESSAGE table, then the messagestore will redeliver the message.
You might need to alter your jbm-queue-service.xml:
Is there a JMS DLQ and an ESB DLQ?
Why is your messages never supposed to reach the DLQ? Is it simply because you always want the redeliveries to continue until they actually succeeds?
How could I access to the JMS and MESSAGE tables? (I am still using the Hypersonic database.)
I tested to set RedeliveryDelay and MaxDeliveryAttempts in jbm-queue-service.xml and this actually affected the redelivery delay and the number of attempts (it worked no mather what useDLQ was set to). I still don't understand the role of the "deploy\jbossesb.esb\META-INF\jboss-esb.xml" file though (since its times and number of attempts didn't match the ones I experienced earlier).
Calle, as I'm also just now experimenting with the JMS-JCA provider I might have some clarifications that I've found that can help you.
@Hans, if my assumptions are clearly wrong you're welcome to correct me. This is just the logic that I've found trough trial and error (and some googling :-)
Since you're using a transaction (JMS-JCA provider) the JMS provider (in this case JBoss Messaging) default transactional error handling kicks in. The action pipeline actually checks whether you're in a transaction or not, and if so leaves the error handling to the JCA provider.
The effect this has is that the JMS provider will roll back the message to it's dead-letter queue as you've found. Any changes you'd like to see must be configured on the JMS provider, not the ESB error handling.
The pre-packaged jbossesb.esb application also contains error handling in the form of i.e. the DeadLetterService and the RedeliveryService, but it never gets called by the action pipeline since you're in a transaction. In my understanding you should think of the esb DeadLetterService as a general DLQ pattern which could be used by any transport, while any JMS provider has it's own dedicated DLQ for transactional rollbacks.
If you want to see this in action, replace your JMS-JCA provider with a non-transacted simple JMS-provider and you'll see the message getting routed to the esb DeadLetterService instead of your JMS DLQ.
@Hans - Have I got my assumptions correct?
I have seen the transactional checks you talk about, and your assumptions make sence when looking at my own experience with the error handling.
A question which comes to mind is what to do when QoS (Quality of Service) is required. Let JMS handle the transaction or let JBossESB handle it for you. Because I'm using JMS to handle the messages, and an Ack is always send when the message is picked up, I came to the conclusion to have JMS work within a transaction. Although infinite message delivery is no possibility, with a customised redelivery delay and a high number of retries it will be really as close to QoS as possible.
So I don't know if my conclusion is right, but I would like to know opinions of others on this subject.