ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ API Support » Deleting a message you have browsed

Post new topic  Reply to topic Goto page Previous  1, 2
 Deleting a message you have browsed « View previous topic :: View next topic » 
Author Message
bruce2359
PostPosted: Thu Mar 13, 2014 5:58 am    Post subject: Reply with quote

Poobah

Joined: 05 Jan 2008
Posts: 9394
Location: US: west coast, almost. Otherwise, enroute.

Something like:
Code:

mqQueue = mqQMgr.AccessQueue(queueName, MQC.MQOO_INPUT  // open queue for input
+ MQC.MQOO_FAIL_IF_QUIESCING);   // but not if MQM stopping

I strongly recommend that you refer to the WMQ Application Programming Reference, and WMQ Application Programming Guide manuals (and InfoCenter equivalents). Read about MQOPEN options and MQGET options. Again, you can't mix MQOO options with MQGMO options.

A quick google search for 'wmq c# browse' resulted in http://stackoverflow.com/questions/18027043/how-do-i-browse-a-websphere-mq-queue-through-all-messages
_________________
I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live.
Back to top
View user's profile Send private message
elomon
PostPosted: Thu Mar 13, 2014 6:31 am    Post subject: Reply with quote

Novice

Joined: 12 Mar 2014
Posts: 10

zpat wrote:
There is this amazing thing - called IBM documentation.

In the Application Programming Reference part - all sorts of magic options are explained.



Thank you zpat, I wish the documentation had been amazing; honestly it's a bit underwhelming when compared with other major product documentation (Oracle, Microsoft, etc). The options are detailed but there are few examples and none for the delete browsed message section. The samples they get installed with MQ Explorer are command line samples, which is not helpful for integration.

zpat wrote:


Even if the queue is open for input - you can still browse a message using the MQGMO_BROWSE_NEXT option.



My original post detailed that using both input and browsing options together threw an error. Also, Bruce is stating I cannot mix open and browsing options - it seems likely this is the cause of the error - we cannot mix open/browse.

I do appreciate you taking the time to reply. I will continue to try to puzzle out what options work for both browsing and opening the queue.
Back to top
View user's profile Send private message
zpat
PostPosted: Thu Mar 13, 2014 6:42 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5849
Location: UK

Try the API exersizer in MO71. This really isn't that complex logic.

I am not sure exactly what you are trying to do, however I think you want to open the queue with input (& browse if you like).

Then get messages with browse next. Then destructively get the message under browse cursor when it passes validation.

Probably a good idea to lock the message under the browse cursor as well.

However you haven't answered my question - what do you do if the message is not validated?

I've worked with IBM software for decades and the documentation is light-years better than other vendors. But because it's not superficial - it can seem difficult to learn the basics from.

There is an application programming guide as well as the reference for this reason.
_________________
Well, I don't think there is any question about it. It can only be attributable to human error. This sort of thing has cropped up before, and it has always been due to human error.
Back to top
View user's profile Send private message
JosephGramig
PostPosted: Thu Mar 13, 2014 6:52 am    Post subject: Re: Deleting a message you have browsed Reply with quote

Grand Master

Joined: 09 Feb 2006
Posts: 1230
Location: Gold Coast of Florida, USA

elomon wrote:
Code:

            MQQueueManager mqQueueManager = new MQQueueManager(QManager);
            MQQueue mqQ = new MQQueue(mqQueueManager, QDown, 8232, QManager, "", "");

            MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions();
            mqGetMessageOptions.Options += MQC.MQGMO_BROWSE_NEXT;
            mqGetMessageOptions.Options += MQC.MQOO_INPUT_SHARED;
                MQMessage mqMessage = new MQMessage();
                mqQ.Get(mqMessage, mqGetMessageOptions); //Exception occurs here

                string msgText = mqMessage.ReadString(mqMessage.MessageLength);

//database logic snipped.

                mqGetMessageOptions.Options = MQC.MQGMO_MSG_UNDER_CURSOR;
                mqQ.Get(mqMessage, mqGetMessageOptions);    //get the message, which deletes it

Change the following line to use open options instead of 8232
Code:

            MQQueue mqQ = new MQQueue(mqQueueManager, QDown, 8232, QManager, "", "");

Move this line to be part of the above line with open options not mqGetMessageOptions.Options
Code:

            mqGetMessageOptions.Options += MQC.MQOO_INPUT_SHARED;
Back to top
View user's profile Send private message AIM Address
bruce2359
PostPosted: Thu Mar 13, 2014 6:57 am    Post subject: Reply with quote

Poobah

Joined: 05 Jan 2008
Posts: 9394
Location: US: west coast, almost. Otherwise, enroute.

As an example, this is from the WMQ APR manual (.pdf):
Quote:
MQOPEN call
For the options of the MQOPEN call:
v At least one of the following must be specified:
– MQOO_BROWSE
– MQOO_INPUT_AS_Q_DEF
– MQOO_INPUT_EXCLUSIVE
– MQOO_INPUT_SHARED
– MQOO_INQUIRE
– MQOO_OUTPUT
– MQOO_SET
v Only one of the following is allowed:
– MQOO_INPUT_AS_Q_DEF
– MQOO_INPUT_EXCLUSIVE
– MQOO_INPUT_SHARED
v Only one of the following is allowed:
– MQOO_BIND_ON_OPEN
– MQOO_BIND_NOT_FIXED
– MQOO_BIND_AS_Q_DEF


It is bad-practice to use the numeric value of the options, as you had done in your code - with 8232. Use the human-readable options form. (Yes, I know that there are examples on IBM's webpages.) Why? Precision in coding, and avoiding needless confusion. Read on.

In order to determine what 8232 means for MQOO, I needed to refer to the WMQ Constants manual. Here are the logical-names and numeric weights. I've highlighted the options that added result in 8232.
MQOO_BIND_AS_Q_DEF 0 X'00000000'
MQOO_READ_AHEAD_AS_Q_DEF 0 X'00000000'
MQOO_INPUT_AS_Q_DEF 1 X'00000001'
MQOO_INPUT_SHARED 2 X'00000002'
MQOO_INPUT_EXCLUSIVE 4 X'00000004'
MQOO_BROWSE 8 X'00000008'
MQOO_OUTPUT 16 X'00000010'
MQOO_INQUIRE 32 X'00000020'
MQOO_SET 64 X'00000040'
MQOO_SAVE_ALL_CONTEXT 128 X'00000080'
MQOO_PASS_IDENTITY_CONTEXT 256 X'00000100'
MQOO_PASS_ALL_CONTEXT 512 X'00000200'
MQOO_SET_IDENTITY_CONTEXT 1024 X'00000400'
MQOO_SET_ALL_CONTEXT 2048 X'00000800'
MQOO_ALTERNATE_USER_AUTHORITY 4096 X'00001000'
MQOO_FAIL_IF_QUIESCING 8192 X'00002000'

Note that 8232 does NOT include an MQOPEN_INPUT_ of any kind.
_________________
I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live.
Back to top
View user's profile Send private message
elomon
PostPosted: Thu Mar 13, 2014 7:34 am    Post subject: Re: Deleting a message you have browsed Reply with quote

Novice

Joined: 12 Mar 2014
Posts: 10

JosephGramig wrote:
elomon wrote:
Code:

            MQQueueManager mqQueueManager = new MQQueueManager(QManager);
            MQQueue mqQ = new MQQueue(mqQueueManager, QDown, 8232, QManager, "", "");

            MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions();
            mqGetMessageOptions.Options += MQC.MQGMO_BROWSE_NEXT;
            mqGetMessageOptions.Options += MQC.MQOO_INPUT_SHARED;
                MQMessage mqMessage = new MQMessage();
                mqQ.Get(mqMessage, mqGetMessageOptions); //Exception occurs here

                string msgText = mqMessage.ReadString(mqMessage.MessageLength);

//database logic snipped.

                mqGetMessageOptions.Options = MQC.MQGMO_MSG_UNDER_CURSOR;
                mqQ.Get(mqMessage, mqGetMessageOptions);    //get the message, which deletes it

Change the following line to use open options instead of 8232
Code:

            MQQueue mqQ = new MQQueue(mqQueueManager, QDown, 8232, QManager, "", "");

Move this line to be part of the above line with open options not mqGetMessageOptions.Options
Code:

            mqGetMessageOptions.Options += MQC.MQOO_INPUT_SHARED;


^This is the key^. Thank you Joseph, and a big thank you to everyone who contributed to the post. I wish the IBM documentation had this or similar as an example but c'est la vie.

Here is the code that browses and then deletes the browsed message, for the sake of someone googling this in the future:


Code:

        string QManager = "Qmgr";
        string QDown = "Qeuue";

            MQQueueManager mqQueueManager = new MQQueueManager(QManager);
            int openOptions = MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_INPUT_SHARED | MQC.MQOO_BROWSE | MQC.MQOO_INQUIRE;
            MQQueue mqQ = new MQQueue(mqQueueManager, QDown, openOptions, QManager, "", "");

            MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions();
            mqGetMessageOptions.Options = MQC.MQGMO_BROWSE_NEXT;;

            while (mqQ.CurrentDepth > 0)

            {
                MQMessage mqMessage = new MQMessage();
                mqQ.Get(mqMessage, mqGetMessageOptions);

                string msgText = mqMessage.ReadString(mqMessage.MessageLength);

 //db save snipped

                //move to the next message or an exception will occur
                mqGetMessageOptions.Options = MQC.MQGMO_WAIT | MQC.MQGMO_BROWSE_NEXT;
}
Back to top
View user's profile Send private message
PaulClarke
PostPosted: Thu Mar 13, 2014 8:05 am    Post subject: Reply with quote

Grand Master

Joined: 17 Nov 2005
Posts: 1002
Location: New Zealand

elomon,

It's all very well to blame the IBM documentation but I don't think that is the whole problem here. As far as I can see what you say now is 'the key' is what I told you to do less than 30 minutes after you originally asked the question.

The problem we often have in software is that we write down the solution but we just can't get people to read it.

Cheers,
Paul.
_________________
Paul Clarke
MQGem Software
www.mqgem.com
Back to top
View user's profile Send private message Visit poster's website
zpat
PostPosted: Thu Mar 13, 2014 8:15 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5849
Location: UK

That's not great code.

You should NEVER reference the queue depth in such a loop.

You should keep the loop going until the end of the queue (MQRC 2033).

This is because messages may have been added since you started the loop (and / or another program may have removed some).

Also I would recommend making the code thread-safe by locking the message under the browse cursor.

Adding MQGMO_CONVERT would make the code support all platform messages (why else use MQ?).

And once again I ask the question - what will you do when your message is NOT validated in the database?
_________________
Well, I don't think there is any question about it. It can only be attributable to human error. This sort of thing has cropped up before, and it has always been due to human error.
Back to top
View user's profile Send private message
elomon
PostPosted: Thu Mar 13, 2014 8:25 am    Post subject: Reply with quote

Novice

Joined: 12 Mar 2014
Posts: 10

PaulClarke wrote:
elomon,

It's all very well to blame the IBM documentation but I don't think that is the whole problem here. As far as I can see what you say now is 'the key' is what I told you to do less than 30 minutes after you originally asked the question.

The problem we often have in software is that we write down the solution but we just can't get people to read it.

Cheers,
Paul.


To be clear - not blaming the documentation for my issue, simply noting it's lacking when compared with modern documentation from other major corporations. The IBM documentation would be at home in the early 90s when bandwidth was tight and we all had to buy books to learn new techniques. It's simply not up to par for 2010s; to say otherwise would be disingenuous.

Your suggestion - to add MQOO_INPUT_SHARED - to the code I presented did not resolve the issue. Joseph's detailed response of what needed to be placed, where, and to remove the numeric representation *was* the key. I honestly and sincerely do appreciate your suggestion and the time you put into this post; your original reply was not, unfortunately, the answer to the problem.


Zpat - the question about what to do was answered in the sixth post on this thread. Thank you for the further suggestions, I will endeavor to incorporate them.

I would be remiss if I did not also specifically thank Bruce for his detailed explanation of the numerical equivalents and that the one I was using did not include an input option. Thanks! I cribbed that from one of the examples and while it worked great for browsing, you are right Bruce - it isn't human readable and led to the situation I found myself in.

Again, a huge thanks to everyone who took the time. I owe you all a round.
Back to top
View user's profile Send private message
PeterPotkay
PostPosted: Thu Mar 13, 2014 12:05 pm    Post subject: Reply with quote

Poobah

Joined: 15 May 2001
Posts: 7717

Do get rid of that queue depth check. There are several reason why a q depth > 0 does not mean you have any messages you can successfully consume. In addition to zpat's points, expired messages and uncomitted messages contribute to qDepth but cannot be gotten.

Code that loops while q depth > 0 screams "I'm an MQ newbie!"
(I know, I did it once, and I was called something less nice than 'newbie' in the code walkthru.)
_________________
Peter Potkay
Keep Calm and MQ On
Back to top
View user's profile Send private message
bruce2359
PostPosted: Thu Mar 13, 2014 1:08 pm    Post subject: Reply with quote

Poobah

Joined: 05 Jan 2008
Posts: 9394
Location: US: west coast, almost. Otherwise, enroute.

elomon wrote:
To be clear - not blaming the documentation ...

Well, actually you are doing just that.

Application development (with WMQ, Oracle, other) is an intermediate-level skill requiring some knowledge of the fundamentals. For WMQ, fundamentals include understanding WMQ objects, and how to use the base MQI calls and structures in order to connect to a qmgr instance, open an object, put/get a message.

The APR and APG manuals are your sources for understanding how to construct (APR) and use (APG) the MQI calls. The more-advanced documentation (Using Java, Using .NET, Using JMS, etc.) presume some knowledge of the base MQI calls.

We're happy to help.
_________________
I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live.
Back to top
View user's profile Send private message
RogerLacroix
PostPosted: Thu Mar 13, 2014 1:13 pm    Post subject: Reply with quote

Jedi Knight

Joined: 15 May 2001
Posts: 3252
Location: London, ON Canada

Hi,

I can't seem to find my C code for getting a my under the cursor but here is the same logic in Java code:

Code:
MQQueue inQ = qMgr.accessQueue( queueName,
                                 MQC.MQOO_INQUIRE + MQC.MQOO_BROWSE + MQC.MQOO_FAIL_IF_QUIESCING + MQC.MQOO_INPUT_SHARED,
                                 null,
                                 null,
                                 null );

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQC.MQGMO_BROWSE_FIRST + MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_ACCEPT_TRUNCATED_MSG;

while (more)
{
   MQMessage getMsg = new MQMessage();

   getMsg.correlationId = MQC.MQCI_NONE;
   getMsg.messageId = MQC.MQMI_NONE;

   inQ.get(getMsg, gmo);

   /* Perform a check for what it is looking for and if found then call getMsgUnderCursor method */
   checkIt(_inQ, getMsg);

   gmo.options = MQC.MQGMO_BROWSE_NEXT + MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_ACCEPT_TRUNCATED_MSG;
}

inQ.close();


Code:
private void getMsgUnderCursor(MQQueue inQ)
{
   MQGetMessageOptions gmo = new MQGetMessageOptions();
   gmo.options = MQC.MQGMO_MSG_UNDER_CURSOR + MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_ACCEPT_TRUNCATED_MSG;

   MQMessage getMsg = new MQMessage();
   //
   getMsg.correlationId = MQC.MQCI_NONE;
   getMsg.messageId = MQC.MQMI_NONE;

   try
   {
      inQ.get(getMsg, gmo, 1);  // only get 1 byte - who cares right!!
   }
   catch (MQException e)
   {
      if (e.completionCode == 1 && e.reasonCode == MQException.MQRC_TRUNCATED_MSG_ACCEPTED)
      {
         // Good message deleted
      }
      else
      {
         if (e.completionCode == 2 && e.reasonCode == MQException.MQRC_NO_MSG_AVAILABLE)
         {
            // And no msg!! Weird.
         }
         else
         {
            logger.error("MQException: " + e.getLocalizedMessage() );
            logger.error("Completion Code = " + e.completionCode + " Reason Code = " + e.reasonCode);
         }
      }
   }
}


The idea is to browse the messages in the queue until you find what you are looking then issue the getMsgUnderCursor method that will delete the particular message.

Regards,
Roger Lacroix
Capitalware Inc.
_________________
Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter
Back to top
View user's profile Send private message Visit poster's website
JosephGramig
PostPosted: Fri Mar 14, 2014 5:18 am    Post subject: Reply with quote

Grand Master

Joined: 09 Feb 2006
Posts: 1230
Location: Gold Coast of Florida, USA

elomon,

I simply could see that you didn't get what was being said in the other posts. WMQ programming might seem simple but it is not.

Before writing anything, understand your requirements thourghly and the tool set with which you intend to solve the problem. Only then, can you design and (finally) code the solution.

"Hurry up and write code. I will tell you what it should do later." will always lead to a pile of steaming poo.
Back to top
View user's profile Send private message AIM Address
tczielke
PostPosted: Mon Mar 24, 2014 6:13 pm    Post subject: Reply with quote

Guardian

Joined: 08 Jul 2010
Posts: 939
Location: Illinois, USA

I noticed there was some mention of using the MQ manual to convert a decimal open options decimal value to its constants. If anyone is looking for a quicker way to do that, the MH06 supportpac provides a tool called mqoptions that will do that for you. It currently handles connect, open, GMO, and PMO options with an executable that runs on Windows, Linux x86, or Solaris SPARC.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Mar 25, 2014 3:21 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

And lastly think about what you are trying to do.
I believe in this case you might want to use some kind of UOW logic with a commit. And perhaps moving the messages that do not validate to a backout queue? ... Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic  Reply to topic Goto page Previous  1, 2 Page 2 of 2

MQSeries.net Forum Index » IBM MQ API Support » Deleting a message you have browsed
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.