|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
IIB9 / Mapping Node with Multiple Assemblies |
« View previous topic :: View next topic » |
Author |
Message
|
akil |
Posted: Tue Nov 04, 2014 1:35 am Post subject: IIB9 / Mapping Node with Multiple Assemblies |
|
|
 Partisan
Joined: 27 May 2014 Posts: 338 Location: Mumbai
|
Hi
I have created an integration service that acts as a facade for HTTP endpoint.
The integration service generates a msg flow as follows:
SoapInput --> SubFlow --> SoapReply
The SubFlow that I have drawn is as follows
Input --> MappingNode1 --> HTTPRequest --> MappingNode2 --> Output
MappingNode1 : takes the incoming payload and creates the request for the outbound call executed by HTTPRequest. In this mapping node I directly work with the XMLNSC domain and I don't have to deal the SOAP_Domain_Msg.
MappingNode2 : is supposed to create either a Fault or a Response. Once again here I am using the XMLNSC domain and not the SOAP_Domain_Msg.
I am having trouble creating conditional messages in the mapping node.
I first tried using the if-else operators. Since these require the children to be siblings, I choose to use the Body tag, as this includes both the Fault and my response. I've put a link to the map
[link]
http://www.pinterest.com/pin/133911788895767698/
[/link]
But this creates the following output (notice the 2 Body tags). I suppose this is because I've included the Body take in the mapping node, and the SoapReply seems to be adding another Body tag around the message.
Code: |
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<out:Body xmlns:out="http://schemas.xmlsoap.org/soap/envelope/" xmlns:io="http://OnlineRechargeService">
<out:Fault>
<faultcode>ERRBV0001</faultcode>
<faultstring>Invalid Authenticator1.</faultstring>
</out:Fault>
</out:Body>
</soapenv:Body>
</soapenv:Envelope>
|
Then I tried creating a mapping node with 2 assemblies, one for the fault and one for the response, and I put a condition on the respective local maps. I've put a link to the map.
[link]
http://www.pinterest.com/pin/133911788895767699/
[/link]
This one works fine for the fault,
Code: |
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<out2:Fault xmlns:out2="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>Server</faultcode>
<faultstring>Invalid Authenticator1.20141104145653</faultstring>
</out2:Fault>
</soapenv:Body>
</soapenv:Envelope>
|
but fails in a successe case. I suppose this happens because the map does not execute the local map (as the conition fails), but still emits the message out, and this being an empty message fails in the SOAP reply.
Code: |
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>BIP3113E: Exception detected in message flow gen.OnlineRechargeService.SOAP Input (broker IB9NODE)</faultstring>
<detail>
<Text>BIP3752E: The SOAP Reply node 'gen.OnlineRechargeService.SOAP Reply' encountered an error while processing a reply message.
An error occurred during reply message processing.
See previous error messages to determine the cause of the error. : /build/slot2/S000_P/src/WebServices/WSLibrary/ImbSOAPReplyNode.cpp: 397: ImbSOAPReplyNode::evaluate: ComIbmSOAPReplyNode: gen/OnlineRechargeService#FCMComposite_1_3
BIP3701E: A Java exception was thrown whilst calling the Java JNI method ''method_com_ibm_broker_axis2_Axis2Invoker_prepareToSendReplyNonSOAP''. The Java exception was ''org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: An invalid XML character (Unicode: 0x48) was found in the prolog of the document.''. The Java stack trace was ''Frame : 0 org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: An invalid XML character (Unicode: 0x48) was found in the prolog of the document.| @: org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:293)| @: org.apache.axiom.om.impl.llom.OMDocumentImpl.getOMDocumentElement(OMDocumentImpl.java:104)| @: org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:568)| @: com.ibm.broker.axis2.SoapUtilities.wrapDataInSoapEnvelopeIfRequiredAvoidingAxis2(SoapUtilities.java:1774)| @: com.ibm.broker.axis2.Axis2Invoker.prepareToSendReplyNonSOAP(Axis2Invoker.java:1271)| @: com.ibm.broker.plugin.MbOutputTerminal._propagate(Native Method)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:133)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:88)| @: com.ibm.broker.ct.mapping.MappingNode.buildAndPropagate(MappingNode.java:677)| @: com.ibm.broker.ct.mapping.MappingNode.evaluate(MappingNode.java:405)| @: com.ibm.broker.plugin.MbNode.evaluate(MbNode.java:1480)| @: com.ibm.broker.plugin.MbOutputTerminal._propagate(Native Method)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:133)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:88)| @: com.ibm.broker.ct.mapping.MappingNode.buildAndPropagate(MappingNode.java:677)| @: com.ibm.broker.ct.mapping.MappingNode.evaluate(MappingNode.java:405)| @: com.ibm.broker.plugin.MbNode.evaluate(MbNode.java:1480)|Frame : 1 javax.xml.stream.XMLStreamException: An invalid XML character (Unicode: 0x48) was found in the prolog of the document.| @: com.ibm.xml.xlxp2.api.stax.msg.StAXMessageProvider.throwWrappedXMLStreamException(StAXMessageProvider.java:76)| @: com.ibm.xml.xlxp2.api.stax.XMLStreamReaderImpl.produceFatalErrorEvent(XMLStreamReaderImpl.java:2008)| @: com.ibm.xml.xlxp2.api.jaxb.JAXBXMLStreamReader.produceFatalErrorEvent(JAXBXMLStreamReader.java:356)| @: com.ibm.xml.xlxp2.scan.DocumentScanner.reportFatalError(DocumentScanner.java:4871)| @: com.ibm.xml.xlxp2.scan.DocumentScanner.reportFatalError(DocumentScanner.java:1212)| @: com.ibm.xml.xlxp2.scan.DocumentScanner.scanProlog(DocumentScanner.java:1777)| @: com.ibm.xml.xlxp2.scan.DocumentScanner.nextEvent(DocumentScanner.java:1323)| @: com.ibm.xml.xlxp2.api.stax.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:581)| @: com.ibm.xml.xlxp2.api.stax.XMLInputFactoryImpl$XMLStreamReaderProxyImpl.next(XMLInputFactoryImpl.java:183)| @: com.ibm.xml.xlxp2.api.wssec.WSSXMLInputFactory$WSSStreamReaderProxy.next(WSSXMLInputFactory.java:55)| @: org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:672)| @: org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)| @: org.apache.axiom.om.impl.llom.OMDocumentImpl.getOMDocumentElement(OMDocumentImpl.java:104)| @: org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:568)| @: com.ibm.broker.axis2.SoapUtilities.wrapDataInSoapEnvelopeIfRequiredAvoidingAxis2(SoapUtilities.java:1774)| @: com.ibm.broker.axis2.Axis2Invoker.prepareToSendReplyNonSOAP(Axis2Invoker.java:1271)| @: com.ibm.broker.plugin.MbOutputTerminal._propagate(Native Method)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:133)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:88)| @: com.ibm.broker.ct.mapping.MappingNode.buildAndPropagate(MappingNode.java:677)| @: com.ibm.broker.ct.mapping.MappingNode.evaluate(MappingNode.java:405)| @: com.ibm.broker.plugin.MbNode.evaluate(MbNode.java:1480)| @: com.ibm.broker.plugin.MbOutputTerminal._propagate(Native Method)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:133)| @: com.ibm.broker.plugin.MbOutputTerminal.propagate(MbOutputTerminal.java:88)| @: com.ibm.broker.ct.mapping.MappingNode.buildAndPropagate(MappingNode.java:677)| @: com.ibm.broker.ct.mapping.MappingNode.evaluate(MappingNode.java:405)| @: com.ibm.broker.plugin.MbNode.evaluate(MbNode.java:1480)''.
Correct the error, and if necessary redeploy the flow. : /build/slot2/S000_P/src/WebServices/WSLibrary/ImbSOAPReplyHelper.cpp: 511: ImbSOAPReplyHelper::makeSOAPReply: :</Text>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
|
I am not sure who to do this in the mapping node, Sure, I can do this with 2 mapping nodes and a filter , but I want to understand if this can be done via the mapping node.
Any ideas? _________________ Regards |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Nov 04, 2014 6:19 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
The mapping node always creates an output message for each output assembly - as you've discovered.
You probably do need to build the output message under the SOAP domain.
Then you can create a conditional mapping to the root element under the Body tag, and a second conditional mapping to the Fault. |
|
Back to top |
|
 |
akil |
Posted: Tue Nov 04, 2014 6:45 am Post subject: |
|
|
 Partisan
Joined: 27 May 2014 Posts: 338 Location: Mumbai
|
For the samples and the documentation it appears that I will need to use the SOAP Domain Msg for the input and the output both... Is that correct ?
I am trying to build a soap reply taking up the response of a http request, can I use the soap domain only in the output ? If so, how do I populate the Context element ? Could you give a few pointers ? _________________ Regards |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Nov 04, 2014 6:54 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
I would tend to put a SoapEnvelope node before the map.
I don't have any specific advice otherwise, sorry. |
|
Back to top |
|
 |
akil |
Posted: Tue Nov 04, 2014 7:36 am Post subject: |
|
|
 Partisan
Joined: 27 May 2014 Posts: 338 Location: Mumbai
|
Hi
I tried the SOAP Domain only on the output assembly, leaving the input assembly as an XMLNSC domain & it worked!!
Should have tried it earlier..
I don't really understand at the moment on how this is working, but am happy it is !.
[url]
http://www.pinterest.com/pin/133911788895768515/
[/url][/url] _________________ Regards |
|
Back to top |
|
 |
akil |
Posted: Tue Nov 04, 2014 9:18 am Post subject: |
|
|
 Partisan
Joined: 27 May 2014 Posts: 338 Location: Mumbai
|
While this approach works for the SOAP flow, it breaks the HTTP flow created by the Mobile pattern...
When using the SOAP domain, the output message from the message model is in the SOAP domain,
Code: |
(0x01000000:Folder):SOAP = ( ['SOAP' : 0x7f8b99b74820]
(0x01000000:Folder):Body = (
(0x01000000:Folder)http://OnlineRechargeService:validateRechargeResponse = (
(0x01000000:Folder ):validateRechargeReply = (
(0x03000000:PCDataField):paymentID = '20141104223631' (CHARACTER)
)
(0x03000102:NamespaceDecl)http://www.w3.org/2000/xmlns/:io = 'http://OnlineRechargeService' (CHARACTER)
)
)
)
)
|
This results in the following JSON from the mobile pattern
Code: |
(0x01000000:Object):JSON = ( ['json' : 0x7f8b99ad7950]
(0x01000000:Object):Data = (
(0x01000000:Object):Body = (
(0x01000000:Object)http://OnlineRechargeService:validateRechargeResponse = (
(0x01000000:Object):validateRechargeReply = (
(0x03000000:NameValue):paymentID = '20141104223631' (CHARACTER)
)
)
)
)
)
|
While if I use separate mapping nodes and stay within the XMLNSC domain, it is
Code: |
(0x01000000:Folder):XMLNSC = ( ['xmlnsc' : 0x7f8b99ae3d90]
(0x01000000:Folder)http://OnlineRechargeService:validateRechargeResponse = (
(0x01000000:Folder ):validateRechargeReply = (
(0x03000000:PCDataField):paymentID = 'hello' (CHARACTER)
)
(0x03000102:NamespaceDecl)http://www.w3.org/2000/xmlns/:out = 'http://OnlineRechargeService' (CHARACTER)
)
)
)
|
This results in the following JSON
Code: |
(0x01000000:Object):JSON = ( ['json' : 0x7f8b980dfca0]
(0x01000000:Object):Data = (
(0x01000000:Object):validateRechargeResponse = (
(0x01000000:Object):validateRechargeReply = (
(0x03000000:NameValue):paymentID = 'hello' (CHARACTER)
)
)
)
)
|
While the SOAPReply node handles both the domain correctly, the mobile pattern does not , it assumes that the sub flow is in the XMLNSC domain, as it simply converts the XML into JSON, including the Body tag .. That's unfortunate, I'll have to either change the way I write the sub flow or I change the generated Java code ...
Which option should I choose? Any guidelines? _________________ Regards |
|
Back to top |
|
 |
martinb |
Posted: Tue Nov 04, 2014 3:05 pm Post subject: |
|
|
Master
Joined: 09 Nov 2006 Posts: 210 Location: UK
|
Hi
Your first attempt gave the nested "Body", because the SOAP Reply node takes your "root" and attaches it under "Body", you caused the extra "Body" by making that your "root".
So the second attempt with two different output Message Assemblies one rooted at "Fault" and the other at your "Operation Response element" would have been correct. However what you needed the Mapping node to do was output one or other. That is achieved by wiring an "If / Else" to to the head of the assemblies - ie wire from If -> whole Message Assembly 1, and Else to whole Message Assembly 2.
Your third attempt works because you are using If / Else to selectively only place one or other child inside Body - since you Mapping node now propagates a SOAP-Domain_msg it just sends that straight - no need to wrap by attaching the provided root element.
Given your observed behavior of the SOAP domain, you need to go back to the two separate Message Assemblies approach, implemented by wiring If / Else to the head of each whole Message Domain. Drag the wire and drop on the "Message Assembly" title area.
HTH
Martin |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
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
|
|
|
|