|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
MQ API Exit - can't get message properties [Solved] |
« View previous topic :: View next topic » |
Author |
Message
|
hopsala |
Posted: Fri Feb 08, 2019 1:08 pm Post subject: MQ API Exit - can't get message properties [Solved] |
|
|
 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 |
|
 |
fjb_saper |
Posted: Sat Feb 09, 2019 8:07 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 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 |
|
 |
hughson |
Posted: Sun Feb 10, 2019 1:56 am Post subject: |
|
|
 Padawan
Joined: 09 May 2013 Posts: 1959 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 |
|
 |
hopsala |
Posted: Mon Feb 11, 2019 6:57 am Post subject: |
|
|
 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 |
|
 |
hughson |
Posted: Mon Feb 11, 2019 1:15 pm Post subject: |
|
|
 Padawan
Joined: 09 May 2013 Posts: 1959 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 |
|
 |
gbaddeley |
Posted: Mon Feb 11, 2019 3:01 pm Post subject: Re: MQ API Exit - can't get message properties |
|
|
 Jedi Knight
Joined: 25 Mar 2003 Posts: 2538 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 |
|
 |
RogerLacroix |
Posted: Mon Feb 11, 2019 3:39 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 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 |
|
 |
hopsala |
Posted: Fri Feb 15, 2019 2:25 pm Post subject: |
|
|
 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 |
|
 |
RogerLacroix |
Posted: Fri Feb 15, 2019 3:07 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 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 |
|
 |
hughson |
Posted: Fri Feb 15, 2019 9:00 pm Post subject: |
|
|
 Padawan
Joined: 09 May 2013 Posts: 1959 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 |
|
 |
hopsala |
Posted: Sat Feb 16, 2019 7:00 am Post subject: |
|
|
 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 |
|
 |
hopsala |
Posted: Sat Feb 16, 2019 7:05 am Post subject: |
|
|
 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 |
|
 |
hughson |
Posted: Sat Feb 16, 2019 7:09 pm Post subject: |
|
|
 Padawan
Joined: 09 May 2013 Posts: 1959 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 |
|
 |
mvic |
Posted: Sun Feb 17, 2019 5:45 am Post subject: |
|
|
 Jedi
Joined: 09 Mar 2004 Posts: 2080
|
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 |
|
 |
RogerLacroix |
Posted: Tue Feb 19, 2019 9:00 am Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 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 |
|
 |
|
|
 |
Goto page 1, 2 Next |
Page 1 of 2 |
|
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
|
|
|
|