Author |
Message
|
Esa |
Posted: Wed Jan 11, 2012 6:10 am Post subject: how to parse a SOAP message with invalid Body to BLOB? |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
I think I know it cannot be done. Broker version < 8. Just checking if somebody knows better.
Untill then I will just have to suppress the invalid element. |
|
Back to top |
|
 |
mgk |
Posted: Wed Jan 11, 2012 7:44 am Post subject: |
|
|
 Padawan
Joined: 31 Jul 2003 Posts: 1642
|
It depends what you mean by invalid body. If your message is a valid XML SOAP message, but just does not match the XML schema then you should be able to process the message by turning of validation on the SOAP Input node. _________________ MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. |
|
Back to top |
|
 |
Esa |
Posted: Wed Jan 11, 2012 8:17 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
True, but this is precisely about logging validation failures. As far as I understand, it does not matter if you validate in the SOAPInput or in a downstream ResenContentDescriptor or whatever.
The root cause is that SOAPInput node - unlike most other input nodes - accesses the actual payload body. And it's never again the virgin BLOB any more. |
|
Back to top |
|
 |
Esa |
Posted: Thu Jan 12, 2012 1:37 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
I have done some more research on this now.
I'm running 6.1.0.5 and I have in my SOAPInput node Validation set to "Content and value" and on the Error Handling tab "Route inbound processing failures to failure terminal" checked. But no matter how invalid requests I send nothing is ever propagated to failure terminal. According to the InfoCenter the message should be propagated as BLOB to failure terminal after a validation failure. If it did that, I would never have needed to think about parsing an already partially parsed SOAP back to BLOB.
I have checked all 6.1. Fix lists up to 6.1.0.10 but there does not seem to be a fix for this. I am also currently unable to check if this works better in V7. But upgrading to 6.1.0.10 is still worth trying? |
|
Back to top |
|
 |
kimbert |
Posted: Thu Jan 12, 2012 1:58 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
If the message has not been changed by the message flow then the original bit stream is still 'valid'. If you call ASBITSTREAM on the message tree you will get the raw message data without incurring any CPU cost for writing the message tree ( there are internal optimizations for this scenario ) |
|
Back to top |
|
 |
Esa |
Posted: Thu Jan 12, 2012 3:31 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
Thanks, kimbert
That's what I thought from the beginning, but I must have totally deviated when my ResetContentDescriptor did'n work the way I expected.
As usual, I had just forgotten to check the three other reset checkboxes when resetting Message Domain to BLOB. This is something I never seem to learn
 |
|
Back to top |
|
 |
Esa |
Posted: Thu Jan 12, 2012 6:52 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
No, it wasn't that after all. For some reason it kicked once but then returned back to throwing the old exception.
kimbert wrote: |
If the message has not been changed by the message flow then the original bit stream is still 'valid'. If you call ASBITSTREAM on the message tree you will get the raw message data without incurring any CPU cost for writing the message tree ( there are internal optimizations for this scenario ) |
By "the message has not been changed" you must mean that InputRoot is still the original one propagated from the input node.
The internal optimizations don't seem to apply to ResetContentDescriptor, only ASBITSTREAM. The flow worked when I changed it to use ASBITSTREAM. You mean that the parser assigned by the input node keeps the original payload BLOB intact even when it has initiated and advanced a parse cursor or even after it has fully parsed the message? If ASBITSTREAM is used to reserialize that message to BLOB, it will just return a pointer to the original BLOB as far as it is not called with confiliction CCSID or encoding parameters.
Is this anywhere near?
Btw, does it apply to MbElement.toBitstream() as well?
This must have been discussed earlier. But I started the topic under false assumptions after searching with wrong keywords. Just trying to learn to apply the good habit of always finishing a topic with a solution or conclusion to serve those who might search the forum in the future. |
|
Back to top |
|
 |
Esa |
Posted: Mon Jan 16, 2012 6:43 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
Still puzzling with this...
Even if I got it finally working (without parsing exceptions) the message was not the original BLOB but an empty SOAP_Domain_Msg (the root message tag from the message set where the wsdl has been imported to).
I finally managed to get the invalid SOAP request propagated to SOAPInput nodes failure terminal. The secret was to set Parse timing to "immediate" as indicated here. That topic discusses the same problem.
kimbert wrote: |
If the message has not been changed by the message flow then the original bit stream is still 'valid'. If you call ASBITSTREAM on the message tree you will get the raw message data without incurring any CPU cost for writing the message tree ( there are internal optimizations for this scenario ) |
Unfortunately I cannot verify these internal optimizations when it comes to SOAPInput. The message propagated to failure terminal is supposed to be a BLOB, but the debugger shows that it belongs to SOAP domain (in fact, the documentation does say it is a SOAP message). If you put that message into a queue either direcly or after resetting it to BLOB with a ResetContentDescriptor or ASBITSTREAM, the message in the queue will contain just an empty SOAP_Domain_msg tag.
So my conclusion remains that you cannot put your hands on the original message received by a SOAPInput node - at least when it is invalid - because the SOAPInput node itself references the message, after which there is no return.
A quote from the topic i referenced above
kimbert wrote: |
If you don't change it to 'Immediate' and your message flow does not reference anything under InputRoot.XMLNSC, then no parsing will occur and no schema validation will occur either. |
To make the the message propagate to failure terminal, you will have to change Parse timing to immediate. But that will force the message to be parsed and turn of the above mentioned internal optimizations.
Another quote from the same thread confirms this:
mgk wrote: |
The second (a regular validation failure message) is generated if the message fails validation which is the type you are seeing. There is no way that I know of at present to get the inbound message as a BLOB in this case, so raise an enhancement request if you need this. |
The user (mqexplorer) said he would raise an enhancement requirement (that was Fri Aug 13, 2010). I have tested with the latest wersion (7.0.0.3). If there ever was an enhancement, it seems that it hasn't been included in the product? |
|
Back to top |
|
 |
kimbert |
Posted: Mon Jan 16, 2012 12:54 pm Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Quote: |
You mean that the parser assigned by the input node keeps the original payload BLOB intact even when it has initiated and advanced a parse cursor or even after it has fully parsed the message? If ASBITSTREAM is used to reserialize that message to BLOB, it will just return a pointer to the original BLOB as far as it is not called with confiliction CCSID or encoding parameters. |
Yes - that's pretty close. To be picky, the parser might have been assigned by a CREATE statement in a Compute node - it doesn't have to be an input node.
You're correct about the SOAP nodes being special - the 'BLOB' in this case is the BLOB that is propagated from the output terminal of the input node - which is not necessarily identical to the message that arrived at the input node ( because of all the web-servicey stuff that goes on inside the node ).
The HTTP nodes also can make minor changes sometimes ( updates to the HTTP header ) on the way through the input node, so the same applies there to a lesser extent.
Quote: |
Btw, does it apply to MbElement.toBitstream() as well? |
Yes - it applies regardless of what mechanism you use to write the message tree - ASBITSTREAM, toBitstream, output node or any other trigger for serialization that the imagination can come up with. |
|
Back to top |
|
 |
Esa |
Posted: Wed Jan 18, 2012 2:46 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
kimbert wrote: |
If the message has not been changed by the message flow then the original bit stream is still 'valid'. If you call ASBITSTREAM on the message tree you will get the raw message data without incurring any CPU cost for writing the message tree ( there are internal optimizations for this scenario ) |
Yes, it works. If you remember to turn off validation with ASBITSTREAM OPTIONS
Or more precisely: it works with a SOAP body that does not validate against the schemas. With a body containing invalid XML the result is naturally less satisfactory.
But the BLOB you get it not a SOAP Request message, it is the serialized SOAP tree the structure of which is described here
OK, I can live with that.
My conclusion is that SOAPReply and SOAPRequest nodes do not use SOAP parser for serializing the message. Instead, they detach selected parts of it and attach them in another message tree that is then serialized using XMLNSC. Or there are some hidden options that can be used to make the SOAP parser do it. |
|
Back to top |
|
 |
whydieanut |
Posted: Tue Dec 11, 2012 2:34 am Post subject: |
|
|
 Disciple
Joined: 02 Apr 2010 Posts: 186
|
So, bottom line - with validations on, it's impossible to get a BLOB of the original input message?
I managed to get this in my Catch Terminal flow:
Code: |
<SOAP_Domain_Msg
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mrm="http://example.com/ai/sangam/sapin">
<Context
operation="myOperation1"
operationType="REQUEST_RESPONSE"
portType="My_PortType"
.
.
.
|
In case of a normal MQ input node with an XMLNSC message, even though the message failed validation, converting it into BLOB would would still give you back the entire original message...
I am working on a common Error Handler (that has to cater to XML/MQ, CSV/FTP, SOAP/HTTP) and this is making the design more and more complex  |
|
Back to top |
|
 |
kimbert |
Posted: Tue Dec 11, 2012 3:52 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
whydieanut said:
Quote: |
So, bottom line - with validations on, it's impossible to get a BLOB of the original input message? |
That statement is not true. It is far too general.
To avoid confusing future readers of this thread, please explain what you really mean - there may be a way to do what you need to do. |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Dec 11, 2012 10:48 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
@esa, If you are looking for an error handler, SOAP is a little bit different.
The error (including validation stuff) will be in the exception tree.
Just evaluate the last 3 levels of the exception tree and get the text for inserts...
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
Esa |
Posted: Wed Dec 12, 2012 1:16 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
fjb_saper wrote: |
@esa, If you are looking for an error handler, SOAP is a little bit different. |
@fjb_saper: my posts in this thread are nearly a year old... I'm not looking for anything any more. |
|
Back to top |
|
 |
whydieanut |
Posted: Wed Dec 12, 2012 2:30 am Post subject: |
|
|
 Disciple
Joined: 02 Apr 2010 Posts: 186
|
kimbert wrote: |
whydieanut said:
Quote: |
So, bottom line - with validations on, it's impossible to get a BLOB of the original input message? |
That statement is not true. It is far too general.
To avoid confusing future readers of this thread, please explain what you really mean - there may be a way to do what you need to do. |
What I meant is,
When using the SOAP Input node, with validations turned on, if there is a validation failure (down the flow), then the message that gets forwarded to the Catch terminal of the SOAP Input node, isn't the same as the original SOAP request that was sent by the sending client application.
In my Error Handler subflow connected to the Catch Terminal of the SOAP Input node, I do an ASBITSTREAM of InputRoot to get a BLOB of the input message (to be stored into a queue).
But the actual message that gets stored in the queue looks like below:
Code: |
<SOAP_Domain_Msg
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mrm="http://example.com/ai/sangam/sapin">
<Context
operation="myOperation1"
operationType="REQUEST_RESPONSE"
portType="My_PortType"
.
.
. |
Instead of the original:
Code: |
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mrm="http://ibm.com/ai/sangam/sapin" >
<soapenv:Body>
<mrm:FIDocumentPosting>
.
.
. |
Is this the expected behaviour, or is there any way to get the original SOAP Request message in the error subflow? |
|
Back to top |
|
 |
|