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 IndexIBM MQ API SupportMQ API Exit - can't get message properties [Solved]

Post new topicReply to topic Goto page 1, 2  Next
MQ API Exit - can't get message properties [Solved] View previous topic :: View next topic
Author Message
hopsala
PostPosted: Fri Feb 08, 2019 1:08 pm Post subject: MQ API Exit - can't get message properties [Solved] Reply with quote

Guardian

Joined: 24 Sep 2004
Posts: 960

Hello friends,

I need to write an API exit (not something I do every day, but now it's necessary) that gets a particular field from the message properties and modifies it.
This will probably hook onto MQPUT, MQGET, MQPUT1. For example if somone does an MQPUT on a message with the property prop1=5, then the exit will increment the counter, and the final message on the queue will have prop1=6.

I've got the IBM sample amqsaxe0.c to work just fine. But I can't figure how I can access message properties.
Oddly, when I look at the logs issued by the IBM sample, I can see no properties on the MQPUT (I use amqsstm sample to do this), and on an MQGET of the same message I see the properties, but only as part of the message buffer as RFH2 header

The exact same code:
Code:
  fprintf(fp, "  Buffer        : %s\n", strptr(ppBuffer,      "0x%p",   buffer1));

Gives an empty log entry for the buffer on the MQPUT:
Quote:
Buffer : 0x000000D28B6FEA88

But on MQGET shows properties as RFH2, as part of the message data:
Quote:
Buffer : 0x00000028B6B0F2D8
00000028B6B0FA80: 52464820 02000000 50000000 22020000 RFH ....P..."...
00000028B6B0FA90: 5E030000 4D515354 52202020 00000000 ^...MQSTR ....
00000028B6B0FAA0: B8040000 28000000 3C757372 3E3C7072 ....(...<usr><pr
00000028B6B0FAB0: 6F703939 393E7072 6F703939 3976616C op999>prop999val
00000028B6B0FAC0: 3C2F7072 6F703939 393E3C2F 7573723E </prop999></usr>


So, my question is:
1. How can I get and modify message properties on MQPUT?
2. Is there a way to get message properties not as part of the message on MQGET? Preferably as key-value pairs (so that I don't have to start going over the buffer bit by bit)

This is for MQ 8 and above

Many thanks!


Last edited by hopsala on Sun May 05, 2019 4:32 am; edited 1 time in total
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Sat Feb 09, 2019 8:07 pm Post subject: Reply with quote

Grand Poobah

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

You either need the MQGMO option for PROPERTIES_IN_HANDLE or you need to set the properties of the queue to specify properties control as properties and not compat. But I see you're dealing with an exit and may have no other alternative than to deal with the RFH2...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
hughson
PostPosted: Sun Feb 10, 2019 1:56 am Post subject: Reply with quote

Grand Master

Joined: 09 May 2013
Posts: 1073
Location: Bay of Plenty, New Zealand

Use the MQMHBUF and MQBUFMH API calls. They were designed for use by API exits.

Cheers,
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
hopsala
PostPosted: Mon Feb 11, 2019 6:57 am Post subject: Reply with quote

Guardian

Joined: 24 Sep 2004
Posts: 960

Great, those are two solid directions. I'll try them out and write back what I find

Thanks a bunch!

p.s Morag your internals presentations have been extraordinarily helpful through the years. Much obliged
Back to top
View user's profile Send private message
hughson
PostPosted: Mon Feb 11, 2019 1:15 pm Post subject: Reply with quote

Grand Master

Joined: 09 May 2013
Posts: 1073
Location: Bay of Plenty, New Zealand

hopsala wrote:
p.s Morag your internals presentations have been extraordinarily helpful through the years. Much obliged

You're very welcome.
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
gbaddeley
PostPosted: Mon Feb 11, 2019 3:01 pm Post subject: Re: MQ API Exit - can't get message properties Reply with quote

Padawan

Joined: 25 Mar 2003
Posts: 1949
Location: Melbourne, Australia

hopsala wrote:
..For example if somone does an MQPUT on a message with the property prop1=5, then the exit will increment the counter, and the final message on the queue will have prop1=6...

Interesting. What is the business / application / technical requirement behind that? Is there a dependency on the counter? (The message could physically undergo multiple puts and gets by MQ internally for message delivery and dead letter processing)
_________________
Glenn
Back to top
View user's profile Send private message
RogerLacroix
PostPosted: Mon Feb 11, 2019 3:39 pm Post subject: Reply with quote

Jedi Knight

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

That's like using a sledge hammer when a screwdriver is needed.

There is a far, far easier way to solve this problem than writing an API Exit. I write exits all the time and I would not do it for this problem!!

A simpler solution would be to go grab the open source code for Pusher (move messages from a queue to another queue) and then modify the PutMessage() subroutine to modify the Named Property.

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
hopsala
PostPosted: Fri Feb 15, 2019 2:25 pm Post subject: Reply with quote

Guardian

Joined: 24 Sep 2004
Posts: 960

gbaddeley and RogerLacroix - thanks for the input. I am aware that exits are being a last resort, as I tell to all my clients. Believe me I wouldn't be doing it if there was another way
I can't specify the exact use case, since this is a product under development, and things are still under wraps.
Suffice to say that this solution was recommended and approved by IBM, even notwithstanding that I am an IBM partner with 20+ years of MQ experience...

RogerLacroix - you mentioned elsewhere on this forum that you can loop through the message properties. Can you give me a quick tip on how to do this? All I can see is an option to get a specifically named property using MQINQMP (which doesn't work yet, see below...)

fjb_saper - thanks, I changed the Q parameter. Not sure what "PROPERTIES_IN_HANDLE" as I don't see that option anywhere. But see below what I tried to do

hughson - From everything I'm reading in the lit and on this forum, I'm supposed to get the properties using the message handle structure... No?

Now to the technical bit:

So I've tried what you suggested, as well as a lot of other things, and I still can't get it to work, even with the help of the samples amqsstma.c and amqsaem.c (which I've seen suggested elsewhere on this forum)

The test is simple:
1. I start the QM
2. do an MQPUT using the sample amqsstm.exe, with a property called "p.1" value "pp"
3. do an MQGET using amqsget
4. stop the QM and collect the logs

Prior to all the register entrypoint calls, I indicate that I want to get all properties starting with "p.":
Code:
    MQXEPO ExitOpts = {MQXEPO_DEFAULT};
      if(memcmp(pExitParms->Hconfig->StrucId, MQIEP_STRUC_ID, 4))
      {
       fprintf(fp, "\nZZZ not good!");
      }

      ExitOpts.ExitProperties.VSPtr    = "p";
      ExitOpts.ExitProperties.VSLength =
        (MQLONG)strlen(ExitOpts.ExitProperties.VSPtr);
 

(not 100% sure I'm supposed to do this. It didn't work either with or without this code bit, although it does change the message buffer)

In order to get the message properties, I tried to get a valid message handle in two ways, but neither worked:

The following code tries to get it from the PMO, returns a value of MQHM_NONE:
Code:
  ((MQGMO)(**ppGetMsgOpts)).MsgHandle);


And trying to get it from exit parameters yields a value of MQHM_UNUSABLE_HMSG:
Code:
pExitParms->ExitMsgHandle


I should note that for now I focused on the MQGET-After entry. I haven't tried this on MQPUT yet

Any ideas? I'm somewhat at a loss, and there is so little information on this in the lit it's super slow-going. Why is MsgHandle empty?

Back to top
View user's profile Send private message
RogerLacroix
PostPosted: Fri Feb 15, 2019 3:07 pm Post subject: Reply with quote

Jedi Knight

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

hopsala wrote:
gbaddeley and RogerLacroix - thanks for the input. I am aware that exits are being a last resort, as I tell to all my clients. Believe me I wouldn't be doing it if there was another way

I still wouldn't do it. My other post is a better solution.

hopsala wrote:
RogerLacroix - you mentioned elsewhere on this forum that you can loop through the message properties. Can you give me a quick tip on how to do this? All I can see is an option to get a specifically named property using MQINQMP (which doesn't work yet, see below...)

Go to the samples directory, open amqsbcg0.c and search for MQINQMP. That code is everything you need.

hopsala wrote:
Prior to all the register entrypoint calls, I indicate that I want to get all properties starting with "p.":
Code:
    MQXEPO ExitOpts = {MQXEPO_DEFAULT};
      if(memcmp(pExitParms->Hconfig->StrucId, MQIEP_STRUC_ID, 4))
      {
      fprintf(fp, "\nZZZ not good!");
      }

      ExitOpts.ExitProperties.VSPtr    = "p";
      ExitOpts.ExitProperties.VSLength =
        (MQLONG)strlen(ExitOpts.ExitProperties.VSPtr);
 

(not 100% sure I'm supposed to do this. It didn't work either with or without this code bit, although it does change the message buffer)

I have no idea what you are doing but I would remove that piece of code.

hopsala wrote:
The following code tries to get it from the PMO, returns a value of MQHM_NONE:
Code:
  ((MQGMO)(**ppGetMsgOpts)).MsgHandle);


And trying to get it from exit parameters yields a value of MQHM_UNUSABLE_HMSG:
Code:
pExitParms->ExitMsgHandle

I have no clue what you are doing? You should do something like:
Code:
if ( (pGMO->Version >= MQGMO_VERSION_4) &&
     (pGMO->MsgHandle != MQHM_NONE) &&
     (pGMO->MsgHandle != MQHM_UNUSABLE_HMSG) )
{
   // now go do work with pGMO->MsgHandle
   // loop thru message properties
}


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
hughson
PostPosted: Fri Feb 15, 2019 9:00 pm Post subject: Reply with quote

Grand Master

Joined: 09 May 2013
Posts: 1073
Location: Bay of Plenty, New Zealand

hopsala wrote:
hughson - From everything I'm reading in the lit and on this forum, I'm supposed to get the properties using the message handle structure... No?


If you don't want to convert the RFH2 buffer into a message property buffer using MQBUFMH, and instead want to use message handles, then read the following in Knowledge Center:-

Using message handles in API exits

Have you looked at sample amqsaem0.c (the Sample API exit that manipulates message properties)?

Cheers,
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
hopsala
PostPosted: Sat Feb 16, 2019 7:00 am Post subject: Reply with quote

Guardian

Joined: 24 Sep 2004
Posts: 960

RogerLacroix wrote:
I still wouldn't do it. My other post is a better solution.

The gyst of it is that I'm writing a product which needs to change MQ behavior for all other MQ apps, without touching their code, so anything except for an exit won't work. I'm afraid I can't specify the exact scenario, so it's hard to start a discussion on whether this is the right solution or not... It's the solution that was proposed by IBM labs at Hursley. Let's just agree to disagree for now, ok?

RogerLacroix wrote:

I have no clue what you are doing? You should do something like:
Code:
if ( (pGMO->Version >= MQGMO_VERSION_4) &&
     (pGMO->MsgHandle != MQHM_NONE) &&
     (pGMO->MsgHandle != MQHM_UNUSABLE_HMSG) )
{
   // now go do work with pGMO->MsgHandle
   // loop thru message properties
}


This is exactly my code. Since the exit gets ppGMO not pGMO, I use **ppGMO.handle. It's the same thing (I know that the code "(MQGMO)(**ppGetMsgOpts)).Field" works, since I'm able to get other fields such as version etc.)

My problem is that for some reason I can't get a valid MsgHandle. When I try to, using both methods I posted above - either pGMO->handle or pExitParms->ExitMsgHandle - I get either MQHM_NONE or MQHM_UNUSABLE_HMSG (on MQGET-after). Any thoughts as to why?

RogerLacroix wrote:
Go to the samples directory, open amqsbcg0.c and search for MQINQMP. That code is everything you need.

Ah, I see now! Thanks!
Funny, I've actually been using this amqsbcg as a reference, but missed that section. In the sample amqsaem.c the only use of MQINQMP appearing there is to a get specific property by name, so I thought that was its only use.

RogerLacroix wrote:
hopsala wrote:
Prior to all the register entrypoint calls, I indicate that I want to get all properties starting with "p.":
Code:
    MQXEPO ExitOpts = {MQXEPO_DEFAULT};
      if(memcmp(pExitParms->Hconfig->StrucId, MQIEP_STRUC_ID, 4))
      {
      fprintf(fp, "\nZZZ not good!");
      }
      ExitOpts.ExitProperties.VSPtr    = "p";
      ExitOpts.ExitProperties.VSLength =
        (MQLONG)strlen(ExitOpts.ExitProperties.VSPtr);
 

(not 100% sure I'm supposed to do this. It didn't work either with or without this code bit, although it does change the message buffer)

I have no idea what you are doing but I would remove that piece of code.

I took this code from the sample amqsaem.c. By what I read in the info center , the property will not be available to the exit if I don't. But I might have misunderstood :
Quote:
You can control which message properties an API exit has access to. Properties are associated with an ExitMsgHandle. Properties set in a put exit are set on the message being put, but properties retrieved in a get exit are not returned to the application.

When you register an MQ_INIT_EXIT exit function using the MQXEP MQI call with Function set to MQXF_INIT and ExitReason set to MQXR_CONNECTION, you pass in an MQXEPO structure as the ExitOpts parameter. The MQXEPO structure contains the ExitProperties field, which specifies the set of properties to be made available to the exit. It is specified as a character string representing the prefix of the properties, which corresponds to an MQRFH2 folder name.

But like I said, I'm not entirely sure I'm supposed to do this. My requirement is to retrieve and set the property value, on both MQGET and MQPUT, and at the end of that process I want it to also be available to the getting application. Not sure I'm going about it the right way

Thanks again
Back to top
View user's profile Send private message
hopsala
PostPosted: Sat Feb 16, 2019 7:05 am Post subject: Reply with quote

Guardian

Joined: 24 Sep 2004
Posts: 960

hughson wrote:
If you don't want to convert the RFH2 buffer into a message property buffer using MQBUFMH, and instead want to use message handles, then read the following in Knowledge Center:-

Using message handles in API exits

Well, my reasoning was that using calls to convert the entire buffer back and forth, on every MQGET and MQPUT would be enormously costly in terms of performance, especially compared to a more direct call that immediately gives me the message properties. This exit is supposed to work on huge client sites with lots of throughput, and is part of a product that's supposed to be 0% impact, so I chose what I thought is the less resource intensive solution. That was my reasoning but I'm open to other considerations

hughson wrote:
Have you looked at sample amqsaem0.c (the Sample API exit that manipulates message properties)?

I did, but I'm still getting an empty message handle. I wrote about it in my reply to RogerLacroix

Thanks
Back to top
View user's profile Send private message
hughson
PostPosted: Sat Feb 16, 2019 7:09 pm Post subject: Reply with quote

Grand Master

Joined: 09 May 2013
Posts: 1073
Location: Bay of Plenty, New Zealand

Without seeing all your API Exit code, it's hard to know what you might have missed.

If you run the amqsaem exit does it work? If you build the amqsaem0.c exit and use properties starting with p instead of properties starting with ApiExit does it work? Does your call to register the initialization entrypoint return a zero CompCode?

Like I say, hard to guess without seeing the code.
Cheers,
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
mvic
PostPosted: Sun Feb 17, 2019 5:45 am Post subject: Reply with quote

Jedi

Joined: 09 Mar 2004
Posts: 2078

hopsala wrote:
This exit is supposed to work on huge client sites with lots of throughput, and is part of a product that's supposed to be 0% impact

Turning the flat RFH2 into a properties hash, then altering the hash (eg. using MQSETMP), then re-flattening, will have a baseline non-negotiable CPU cost.
No-one could believe it is possible to write a 0-cost exit, no matter what it does.
Back to top
View user's profile Send private message
RogerLacroix
PostPosted: Tue Feb 19, 2019 9:00 am Post subject: Reply with quote

Jedi Knight

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

If the MQ application sets 'MQGMO_PROPERTIES_FORCE_MQRFH2' for MQGMO's options field or the queue attribute 'PROPCTL' is set to force then the API Exit will always get an MQRFH2 message.

So, you either handle it as an MQRFH2 message or use MQBUFMH.

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
Display posts from previous:
Post new topicReply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum IndexIBM MQ API SupportMQ API Exit - can't get message properties [Solved]
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.