I have reached the ibm site but I cant find the actual logic to make use of the trigger.
I have done the below code but how can i receive an intimation from the trigger?
public void setTrigger()
{
try{
Queue = QMGR.accessQueue(queueName, (MQC.MQOO_INQUIRE+MQC.MQOO_SET));
Queue.setTriggerControl(1);
Queue.setTriggerType(2);
}
catch(Exception e){
System.out.println("------------------------");
System.out.println("trigger method");
System.out.println("------------------------");
System.out.println(e);
System.out.println("************************");
}
}
How can I get the intimation whenever message came.
First off, don't do the triggering setup via an application. It is a waste of time.
Secondly, read & understand these MQ web pages:
Starting IBM MQ applications using triggers > Prerequisites for triggering
Starting IBM MQ applications using triggers
Third, for Java applications, create a batch file or Unix script to set up any environment variables i.e. CLASSPATH and set batch file or Unix script in the PROCESS's APPLICID field.
Fourth, after you do the MQSC definition for the queue and process, don't forgot to start the trigger monitor (otherwise nothing will be triggered).
Fifth, if you set Trigger Type of First then make absolutely sure that the triggered application reads every message from the queue before exiting.
Sixth, triggering (Trigger First) is only good for scenarios when there are large gaps between messages or large gaps between burst of messages. If you are receiving messages every second or 2 then triggering is not good because the application start, process & exit every second or 2. And if it is a Java application, you will always have the JVM load time.
Seventh, if what you really wanted was Message CallBack (Asynchronous) rather than MQ Triggering then go read: Asynchronous consumption of IBM MQ messages
Related
We have a requirement in where we need to send only one message at a time to a backend process. The call back of this process takes around an hour, only after the call back can we send another request to the process.
I am trying to achieve this by using a manager bpel process that will hold the messages first if there is already something being processed in the backend, and then send it once it realizes that the backend is free. This approach will work, but our architect wants a cleaner solution. He suggested using JMS queues. The idea is for the jms queue to messages to be read by a amanger one at a time, only moving on to the next one once we receive the callback from the backend and we know that the composite and bpel instance is finished. I've been scouring the internet for weeks, but I couldn't find a working jms based solution for my requirement.
I've tried the suggestions for this link but turning on unit of order and acknowledgement properties does nothing.
Try this approach!!
Use a event driven bpel process.
Use a database flag as your next trigger. (flag is TRUE)
jms Adapter receives first message from the queue. Here use a delay in the adapter since you are expecting the bpel to be long running. use below setting.
<binding.jca config="MyServiceInboundQueue_jms.jca">
<property name="minimumDelayBetweenMessages">10000</property>
<property name="singleton">true</property>
</binding.jca>
if flag == TRUE in the db causes the db adapter to proceed with the bpel process,
else skip the bpel.
mark flag==FALSE
call the backend system
callback is received after an hour.
set flag==TRUE
Hi Jonar,
At my company we always use JMS queues for Asynchronous messaging. You could do with a delay timer build in your composite set to 1 hour and 15 minutes for example, and it will work most of the time, but its hella messy. The whole idea is for any asynchronous process to kick off when a message is put upon its queue target (specified by the JMS queue). The JMS adapter in the composite of your project will pick up the message from the queue when it is free to process the queue. The goal for you would be to put the message on the queue and pick it up from it using the adapter. It will know which message to pick up because you specify which queues it listens to in the adapter.
The following blog post by John-Brown Evans eplains the whole process from step one. It might be a bit tedious, but I found it very helpful. Its using SOa Suite 11g instead of the nowadays more commonly used 12c, but its fundamentals remain the same.
Awesome JMS queue tutorial
I hope this works for you!
Cheers,
Jesper
We have an HA application which runs on a few servers pointing to the same queue manager. Because the message sequencing is important we use a semaphore queue to make sure not two apps are reading messages from a business queue even if there are multiple messages waiting to be processed on that queue.
The work flow is something like below:
The business queue has a MQTT_DEPT trigger set on it to fire up when the queue dept is equals to one
The business queue receives one or multiple massages.
The trigger fires up when the queue dept becomes one and put a trigger message into an initiation queue.
Being a queue dept trigger it should switch itself OFF after delivering the trigger message into the initiation queue
There is a MDB listening to that initiation queue which gets the trigger messaage
Because sequence is crucial for us we put a limit on the initiation queue to have the maximum queue dept of one. This way only one MDB can get a message at a time
When the trigger message arrives the MDB goes and reads all messages from the business queue and when done it sends a trigger activate message to a dedicated queue.
Once this is done it commits everything. The trigger generated message gets discarded. At this point the trigger activation message becomes available for processing.
A trigger activating MDB gets the activation message and go and switches the queue dept trigger back on on the business queue so the whole process can kick off again.
In most of the cases all works fine. However now and then we get some messages in the dead letter queue which causes support calls by our monitoring tools. Inspecting the messages in the DLQ we noticed they are trigger generated messages and the reason for being sent to the DLQ is that the initiation queue was full (remember our limit of maximum one message).
We had no explanation about how this is possible. The IBM documentation says the triggering is switched off after sending the first trigger generated message but however from what we are experimenting it looks like wile the first trigger generated message gets processed and such is in an uncommitted state a second trigger generated message gets created and sent to the initiation queue. Not being able to deliver it (because of the max dept = 1 limit) it sends it to the dead letter queue.
Any inputs about why this would be possible and how to get around it would be very welcome. False support calls at 2:00AM are for sure not funny.
Thank you in advance for your inputs.
The explanation for our problem was on the IBM MQ triggering documentation which we should read more carefully IBM note:
Note: If you stop and restart the queue manager, the TriggerInterval timer is reset. There is a small window during which it is possible to produce two trigger messages. The window exists when the trigger attribute of the queue is set to enabled at the same time as a message arrives and the queue was not previously empty (MQTT_FIRST) or had TriggerDepth or more messages (MQTT_DEPTH).
Once we had the explanation the solution was simple. Rather than configuring the business queue to send the trigger generated message straight to the initiation queue we configured it to send to a different queue whit ho maximum queue dept restriction set on it. Then we implemented another MDB to get these trigger generated messages and redirect them to the initiation queue. This MDB was implemented two swallow any exception caused by an unable to deliver trigger generated message to the initiation queue because the existing queue dept limitation.
In other words with this new MDB we took the role of delivering the trigger generated message from the MQ manager in our hands and made the process ignore any delivery failure caused by the queue dept.
We have an environment where MQ acts as an interface between
Websites and Micro Focus. Sometimes a message gets stuck in a queue,
thereby blocking all the communications over that particular queue. If
the queue depth increases greatly, all the communication stops in the
queue manager.
When we check the status of queue, we see that microfocus process is present there.
Is there are way to automatically clear all applications connected to the queue?
I don't think its possible to close an applications handle on a given queue but you could have a script that runs a couple of MQSC commands against the queue manager to first get the connection identifier using the DISPLAY CONN command and then close the connection using the STOP CONN command. You could then setup a trigger on the queue that executes the script once a certain queue depth has been reached.
I'm looking for a way to schedule a MDB. My requirement is that the MDB is set to feed a system from the company. This system goes out for maintenance every night, but the other systems don't know about it and may keep trying to feed it. A persistent queue is great in the way that my messages could be pilled until system goes back online.
How could I manage that? I've run into that already: schedule a message driven bean to access a queue during certain times? but it uses java 7, and worst, message is lost if the server restarts (messages is taken out of the JMS Queue and kept in memory until timer process it).
Another use of this would be to implement a "retry" queue. In case of error I want to retry processing my message, but not immediately, after a certain amount time only.
Any ideas to keep my MDB offline for a certain amount of time?
Most versions of JBoss publish a management MBean that allows you to stop delivery on a MDB.
If you're using EJB3, however, they auto-start, so you will need to register a startup class to stop starting MDBs at boot time if boots occur in your MDB's blackout period. Once past that snafu, you can schedule a simple quartz job to start and stop the MDBs according to your delivery windows.
Well, it looks like there is no way to pause a MDB in a generic way. The best solution is, like most people will answer, to use the DLQ (or DMQ).
Now, if I want to introduce a timer on a message, I set the time to live of the producer to the amount of time I want the message to wait. Then I send it to a normal queue, lets say waitingQueue which has no consumer. After expiration, the message is sent to default destination (mq.sys.dmq for Glassfish MQ, make sure to create a jms resource with mq.sys.dmq as imqDestinationName). I have a MDB listening to the error queue and responsible of sending the message again. Now, if I want to "close" a queue for some time, when a message arrives in the queue, I check if current time is allowed or not. Just set the time to live to the amount of time before next opening hours and send it to waitingQueue.
The reason I didn't use it since the beginning is that I fell into a few pitfalls. Here are a few useful properties to set when using DMQ with Glassfish 3.1.1 and its embedded MQ.
imq.message.expiration.interval=1 that's for the poll interval on each queue before sending timed out messages to the DMQ. Default is 60 seconds. If like me you want to test your application with little latency, this is what you need.
What is the best approach to connect to websphere mq v7.1 and clear all the messages of one or more specified queues using Java and JMS? Do I need to use Websphere MQ specific java API? Thanks.
Like all good questions, "it depends."
The queue can be cleared with a command only if there are no open handles on the queue. In that case sending a PCF command to clear the queue is quite effective, but if there are open handles you get back an error. PCF commands are of course a Java feature and not JMS because they are proprietary to WebSphere MQ.
On the other hand, any program authorized to perform destructive gets off a queue can clear the queue. In this case, just loop over a get until you get the 2033 return code indicating the queue is empty. This can be performed using JMS or Java but both of these manage the input buffer for you. If the queue is REALLY deep then you end up moving all that data and if the app is client connected, you are moving it at network speed instead of in memory.
To get around this, you need to specify a minimal amount of buffer and as one of the GET options also specify MQGMO.TRUNCATED_MSG_ACCEPTED. This moves only the message header during the get calls and can be significantly faster.
Finally, if you are doing this programamtically and regardless of which method you use, spin off several threads and don't use syncpoint. You actually have to go out of your way to get exclusive input on a queue so once you get a session, just spawn many threads off of it. Close each thread gracefully and shut down the the session once all the threads are closed.