Author |
Message
|
KIT_INC |
Posted: Sun Jun 24, 2012 1:47 pm Post subject: Save and restore MRM message for Reply |
|
|
Knight
Joined: 25 Aug 2006 Posts: 589
|
I have a requirement to return the original MRM message with only 1 field (ERROR_ID) updated when an error is detected within the flow. The message is very complex with close to 500 fields. I tried to do a simple test case. I use a very simple flow
MQInput --> Compute --> compute ....
The MQInput (MRM Domain with msgset and msgtype specified) parsed the message with no error.
The first ESQL in the 1st compute node is to save the Input tree
SET Environment.Input = Input Root;
process the message
If everything is fine propagate to terminal 'out1'
If error detected propagate to terminal 'out2'
I have the 2nd compute node wired to out2 of the 1st compute node. It has an ESQL statement
SET OutputRoot= Enviroment.Input
to restore the Input message
SET OutputRoot.MRM.MY_MSG.ERROE_ID='123';
I thought that this is the simpliest way to do this.
But the statement
SET OutputRoot= Enviroment.Input
failed with error
( MB7BROKER.default ) Unable to resolve union for the ''5'' child of element ''(0x0100001B:Name+):MRM''. Additional diagnostic information is ''1c434e4c''
An incoming message contained a union which was neither resolved by the message's tagging nor by the accesses made by SQL statements. Either the message was of an unexpected type or there is an error in the SQL. See earlier messages for details of the node in which this error occurred and the action taken as a result.
Check that the incoming messages are of the correct type and that the logic of the SQL of the node in which the error occurred
Is this the proper way save and restiore an MRM message ?
Any suggestion ? |
|
Back to top |
|
 |
KIT_INC |
Posted: Sun Jun 24, 2012 2:07 pm Post subject: |
|
|
Knight
Joined: 25 Aug 2006 Posts: 589
|
I take a look at the message definition, the 5th element is a redefine (choice element) that's probably the reson for the error. This message defintion file has redefines all over the place. I hope that I do not end up have to write ESQL statement for every field. Is there anyway to tell the broker to use a default choice when not specified? |
|
Back to top |
|
 |
mqjeff |
Posted: Sun Jun 24, 2012 4:33 pm Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
CWF can't resolve choices automatically, as far as I remember.
TDS can use tags and delimiters to resolve choices. It can also use Data Patterns, but they are the choice of last resort from a performance perspective, if you'll forgive the selection of word.
DFDL, of course, is better at all of this than either CWF or TDS.
There is almost always more than one way to model the same record. Some enlightened meditation on your particular format may provide some ideas on how to restructure the model such that MRM can parse it automatically. |
|
Back to top |
|
 |
mqjeff |
Posted: Sun Jun 24, 2012 4:35 pm Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Also, of course, two other things.
One, you're better off saving the bitstream for replay or reparse than saving the parsed tree.
Two, I do not think that your
Code: |
Set Environment.Input = InputRoot; |
does what you think it does. I suspect you'll find that this may not preserve the parser properly. |
|
Back to top |
|
 |
KIT_INC |
Posted: Sun Jun 24, 2012 6:59 pm Post subject: |
|
|
Knight
Joined: 25 Aug 2006 Posts: 589
|
If my memory serve me right, Saving the input as bistream and use create parse to recreate the MRM structure on output will failed with the same unknown choice situation. I think I have seen that a couple of months ago for another flow. I'll try and confirm again. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Jun 24, 2012 7:13 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
KIT_INC wrote: |
If my memory serve me right, Saving the input as bistream and use create parse to recreate the MRM structure on output will failed with the same unknown choice situation. I think I have seen that a couple of months ago for another flow. I'll try and confirm again. |
If you can have the inputstream before any parsing occurred, try a content redescriptor node for the BLOB domain and your output message should look just like your input message...
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
Nikswe |
Posted: Sun Jun 24, 2012 10:50 pm Post subject: |
|
|
Newbie
Joined: 28 May 2012 Posts: 9 Location: Stockholm
|
Instead of saving the entire message in environment, wouldn't it be better to use the catch terminal of the input node (or another node). The error could be stored in environment. This way you do not need to have a copy of your message for successful transactions.
Good luck! |
|
Back to top |
|
 |
KIT_INC |
Posted: Wed Jun 27, 2012 7:03 am Post subject: |
|
|
Knight
Joined: 25 Aug 2006 Posts: 589
|
I saved the InputRoot using ASBITSTREAM and when I tried to recreate using Create Parse, it failed at the redefine (choice element). So my memory is right,
I can output the exact same message as Input by
Set OutputRoot.BLOB.BLOB = the BLOB I saved using Asbitstream, But that does not help me to update the one field that I needed. The only way is to use substring function to upodate the BLOB before I outoput it.
But what if I have to update a number of fields, using substring seems to be a primitive way.
I was hoping that I can parse it into the MRM tree and update whatever fields I need. But I am stuck on the redefines in the message set.
I'll see if I have better luck using the Catch terminal as suggested. |
|
Back to top |
|
 |
KIT_INC |
Posted: Wed Jun 27, 2012 10:01 am Post subject: |
|
|
Knight
Joined: 25 Aug 2006 Posts: 589
|
Yes, I can have the inut message at the catch terminal. This is better because I do not have to save and carry the input message thodough the flow. However this does not help me when I want to update only a few fields out of the several hundred before returning the message to the user. I run into the choice probelm once I update a field of the messsage and output it.
For example in the catch terminal, I do
Set outputRoot=InputRoot
and do a MQreply, the entire input message will be PUT to the REplyToQ.
But if I want to update a field, like
Set outputRoot=InputRoot;
SET OutputRoot.MRM.MY_MSG.ERROE_ID='123';
(OutputRoot.MRM.MY_MSG.ERROE_ID is blank in the Input message)
It will fail with the error due to unresolved choice. Even MY_MSG.ERROE_ID is not within any of the redefined block.
Look like that once the MRM parser is invoke, the choice must be made before it will output the message without any error.
It still seems that substring is the only way to do it. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Jun 27, 2012 10:13 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Substring is not the only way to do it.
Substring is, probably, the "easiest" way to do it.
But if you can write a reasonable substring, you can just as reasonably write two new message definitions that treat the data in the same way as substring does. I.e. one message definition to split the BLOB into two pieces, and one to hold the new field between the two pieces.
The real question is - how much of the rest of the message do you need?
And. If the reason you're having to insert an error code is that the message doesn't parse in the first place - it doesn't really help to insert an error code. The message will still not be parsable so you still won't be able to extract the error code that says the message isn't parsable....
Again, you should probably look at ways to modify your message set so that it can resolve the choices for you. Or look at the ways that the other flows already resolve the choices when dealing with this message.. |
|
Back to top |
|
 |
kimbert |
Posted: Wed Jun 27, 2012 12:34 pm Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Quote: |
And. If the reason you're having to insert an error code is that the message doesn't parse in the first place - it doesn't really help to insert an error code. The message will still not be parsable so you still won't be able to extract the error code that says the message isn't parsable.... |
Just what I was going to point out. Sounds like a rather risky error recovery strategy to me. |
|
Back to top |
|
 |
KIT_INC |
Posted: Wed Jun 27, 2012 1:12 pm Post subject: |
|
|
Knight
Joined: 25 Aug 2006 Posts: 589
|
We are in the design stage for an application flow. The requirement is to return the original input message to the user with a few fields updated. One of the them is an error code field. We have standard error rountines to capture exceptions. So any broker detected problem will be logged and the message will be backout to a backout queue. The discussion here is more on an user detected error than any standard broker detected error.
The Input message has many refines. As we process the message inside the flow, these redefines will all get resolved and the output will be fine.
The situations is in the lfow we have a check for number of Items returned from DB, the the item is bigger than a number, we want to return the entire message the user using MQREPLY node with an error code and the item description and numbers. Since we want to stop here and send the reply, we have not make decsisons on many of the redefine yet. We were hoping that , if we save the Input after the MQInput and restore what we saved at this point, we can just update a couple of fileds and return it to the user. That how we start getting into the unresolve choice and hence this discussion here. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Jun 27, 2012 2:37 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
You fail at the PARSE because you have a timing of parse immediate and not parse on Demand.
With redefines you need to do parse on demand and request a specific branch of the redefine choice. Then the rest will parse. If you have a lot of redefines you need to select for each one before parsing anything that comes after the redefines, whether it is part of the redefines or not...
If I know in advance, I usually make those the first statements in the on demand parsing so I don't have to think about it afterwards...
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
|