Saturday, April 22, 2017

Sending Single character < in a message which goes through a XSLT transformation WSO2 ESB 4.9.0

When we try to send a message which holds single character &lt; we will encounter a problem as explained in [1].

[1] http://ajanthane.blogspot.com/2017/04/reason-behind-comctcwstxexcwstxunexpect.html

Take the below request:
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org">  
   <soapenv:Header/>  
   <soapenv:Body>  
    <Description>Test for escaping &lt; &gt; characters</Description>  
   </soapenv:Body>  
 </soapenv:Envelope>  

Which goes through a sample proxy as below:
 <?xml version="1.0" encoding="UTF-8"?>  
 <proxy xmlns="http://ws.apache.org/ns/synapse"  
     name="CheckXSLTEscapeCharacters"  
     transports="https,http"  
     statistics="disable"  
     trace="disable"  
     startOnLoad="true">  
   <target>  
    <inSequence>  
      <log level="custom">  
       <property name="STATUS"  
            value="--------------------CheckXSLTEscapeCharacters Invoked--------------------"/>  
      </log>  
      <log level="full"/>  
      <log level="custom">  
       <property name="STATUS"  
            value="--------------------CheckXSLTEscapeCharacters After Log full Invoked--------------------"/>  
      </log>  
      <xslt key="conf:TransformationXSLT.xslt"/>  
      <log level="custom">  
       <property name="STATUS"  
            value="--------------------CheckXSLTEscapeCharacters Invoked After XSLT Transformation--------------------"/>  
      </log>  
      <respond/>  
    </inSequence>  
   </target>  
   <description/>  
 </proxy>  

The XSLT used here is as below:
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">  
   <xsl:output method="xml" indent="yes" cdata-section-elements="Description"/>  
   <xsl:preserve-space elements="*" />  
   <xsl:template match="Description">  
     <Description>  
      <xsl:value-of select="." disable-output-escaping="yes" />  
     </Description>  
   </xsl:template>  
   <xsl:template match="@*|node()">  
     <xsl:copy>  
       <xsl:apply-templates select="@*|node()"/>  
     </xsl:copy>  
   </xsl:template>  
 </xsl:stylesheet>  

During this will get an error as below:
 [2017-04-21 21:15:23,882] DEBUG - wire >> "POST /services/CheckXSLTEscapeCharacters HTTP/1.1[\r][\n]"  
 [2017-04-21 21:15:23,883] DEBUG - wire >> "Accept-Encoding: gzip,deflate[\r][\n]"  
 [2017-04-21 21:15:23,883] DEBUG - wire >> "Content-Type: text/xml;charset=UTF-8[\r][\n]"  
 [2017-04-21 21:15:23,883] DEBUG - wire >> "SOAPAction: "urn:echoString"[\r][\n]"  
 [2017-04-21 21:15:23,883] DEBUG - wire >> "Content-Length: 281[\r][\n]"  
 [2017-04-21 21:15:23,883] DEBUG - wire >> "Host: ajanthan-ThinkPad-T440p:8280[\r][\n]"  
 [2017-04-21 21:15:23,884] DEBUG - wire >> "Connection: Keep-Alive[\r][\n]"  
 [2017-04-21 21:15:23,884] DEBUG - wire >> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"  
 [2017-04-21 21:15:23,884] DEBUG - wire >> "[\r][\n]"  
 [2017-04-21 21:15:23,884] DEBUG - wire >> "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org">[\n]"  
 [2017-04-21 21:15:23,884] DEBUG - wire >> "  <soapenv:Header/>[\n]"  
 [2017-04-21 21:15:23,885] DEBUG - wire >> "  <soapenv:Body>[\n]"  
 [2017-04-21 21:15:23,885] DEBUG - wire >> "   <Description>Test for escaping &lt; &gt; characters</Description>[\n]"  
 [2017-04-21 21:15:23,885] DEBUG - wire >> "  </soapenv:Body>[\n]"  
 [2017-04-21 21:15:23,885] DEBUG - wire >> "</soapenv:Envelope>"  
 [2017-04-21 21:15:23,917] INFO - LogMediator STATUS = --------------------CheckXSLTEscapeCharacters Invoked--------------------  
 [2017-04-21 21:15:23,917] INFO - LogMediator To: /services/CheckXSLTEscapeCharacters, WSAction: urn:echoString, SOAPAction: urn:echoString, MessageID: urn:uuid:4e549a72-8b19-494f-84a9-351509a2b184, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org"><soapenv:Body>  
    <Description>Test for escaping &lt; > characters</Description>  
   </soapenv:Body></soapenv:Envelope>  
 [2017-04-21 21:15:23,917] INFO - LogMediator STATUS = --------------------CheckXSLTEscapeCharacters After Log full Invoked--------------------  
 [2017-04-21 21:15:31,664] ERROR - XSLTMediator Unable to perform XSLT transformation using : Value {name ='null', keyValue ='conf:TransformationXSLT.xslt'} against source XPath : s11:Body/child::*[position()=1] | s12:Body/child::*[position()=1] reason : com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character ' ' (code 32) in content after '<' (malformed start element?).  
  at [row,col {unknown-source}]: [2,33]  
 org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character ' ' (code 32) in content after '<' (malformed start element?).  
  at [row,col {unknown-source}]: [2,33]  
      at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296)  
      at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)  
      at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)  
      at org.apache.axiom.om.impl.llom.OMElementImpl.detach(OMElementImpl.java:700)  
      at org.apache.axiom.om.impl.llom.OMNodeImpl.setParent(OMNodeImpl.java:105)  
      at org.apache.axiom.om.impl.llom.OMNodeImpl.insertSiblingAfter(OMNodeImpl.java:203)  
      at org.apache.synapse.mediators.transform.XSLTMediator.performXSLT(XSLTMediator.java:360)  
      at org.apache.synapse.mediators.transform.XSLTMediator.mediate(XSLTMediator.java:196)  
      at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)  
      at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)  
      at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)  
      at org.apache.synapse.core.axis2.ProxyServiceMessageReceiver.receive(ProxyServiceMessageReceiver.java:185)  
      at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)  
      at org.apache.synapse.transport.passthru.ServerWorker.processEntityEnclosingRequest(ServerWorker.java:395)  
      at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:142)  
      at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)  
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)  
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)  
      at java.lang.Thread.run(Thread.java:745)  
 Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character ' ' (code 32) in content after '<' (malformed start element?).  
  at [row,col {unknown-source}]: [2,33]  
      at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:639)  
      at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2843)  
      at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1072)  
      at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)  
      at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)  
      at org.apache.axiom.om.impl.llom.OMElementImpl.buildNext(OMElementImpl.java:653)  
      at org.apache.axiom.om.impl.llom.OMNodeImpl.getNextOMSibling(OMNodeImpl.java:122)  
      at org.apache.axiom.om.impl.traverse.OMChildrenIterator.getNextNode(OMChildrenIterator.java:36)  
      at org.apache.axiom.om.impl.traverse.OMAbstractIterator.hasNext(OMAbstractIterator.java:58)  
      at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:554)  
      at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:875)  
      at org.apache.axiom.om.impl.llom.OMSerializableImpl.serialize(OMSerializableImpl.java:125)  
      at org.apache.axiom.om.impl.llom.OMSerializableImpl.serialize(OMSerializableImpl.java:113)  
      at org.apache.axiom.om.impl.llom.OMElementImpl.toString(OMElementImpl.java:988)  
      at org.apache.synapse.mediators.transform.XSLTMediator.performXSLT(XSLTMediator.java:310)  
      ... 12 more  
 [2017-04-21 21:15:31,671] INFO - LogMediator To: /services/CheckXSLTEscapeCharacters, WSAction: urn:echoString, SOAPAction: urn:echoString, MessageID: urn:uuid:4e549a72-8b19-494f-84a9-351509a2b184, Direction: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = Unable to perform XSLT transformation using : Value {name ='null', keyValue ='conf:TransformationXSLT.xslt'} against source XPath : s11:Body/child::*[position()=1] | s12:Body/child::*[position()=1] reason : com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character ' ' (code 32) in content after '<' (malformed start element?)., Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org"><soapenv:Body>  
    <Description>Test for escaping &lt; > characters</Description>  
   </soapenv:Body></soapenv:Envelope>  
 [2017-04-21 21:15:31,672] DEBUG - wire << "HTTP/1.1 202 Accepted[\r][\n]"  
 [2017-04-21 21:15:31,673] DEBUG - wire << "Date: Fri, 21 Apr 2017 15:45:31 GMT[\r][\n]"  
 [2017-04-21 21:15:31,673] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"  
 [2017-04-21 21:15:31,673] DEBUG - wire << "Connection: Keep-Alive[\r][\n]"  
 [2017-04-21 21:15:31,674] DEBUG - wire << "[\r][\n]"  
 [2017-04-21 21:15:31,674] DEBUG - wire << "0[\r][\n]"  
 [2017-04-21 21:15:31,674] DEBUG - wire << "[\r][\n]"  

To overcome this we need to follow the below steps.

1) Create a file named XMLInputFactory.properties inside ESB_HOME folder.

2) Add the below content to it.
javax.xml.stream.isCoalescing=false

3) Make sure to enable cdata-section-elements in the XSLT file. I have already enabled it in the above sample and provided the Description tag, which is the one holds the data which needs to be passed as CDATA segment.

Also make sure that disable-output-escaping="no" in the XSLT stylesheet.

4) Now send the same request. Will get the below log which indicates that we successfully sent the message.
 [2017-04-21 21:28:06,529] DEBUG - wire >> "POST /services/CheckXSLTEscapeCharacters HTTP/1.1[\r][\n]"  
 [2017-04-21 21:28:06,531] DEBUG - wire >> "Accept-Encoding: gzip,deflate[\r][\n]"  
 [2017-04-21 21:28:06,531] DEBUG - wire >> "Content-Type: text/xml;charset=UTF-8[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "SOAPAction: "urn:echoString"[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "Content-Length: 281[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "Host: ajanthan-ThinkPad-T440p:8280[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "Connection: Keep-Alive[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "[\r][\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org">[\n]"  
 [2017-04-21 21:28:06,532] DEBUG - wire >> "  <soapenv:Header/>[\n]"  
 [2017-04-21 21:28:06,533] DEBUG - wire >> "  <soapenv:Body>[\n]"  
 [2017-04-21 21:28:06,533] DEBUG - wire >> "   <Description>Test for escaping &lt; &gt; characters</Description>[\n]"  
 [2017-04-21 21:28:06,533] DEBUG - wire >> "  </soapenv:Body>[\n]"  
 [2017-04-21 21:28:06,533] DEBUG - wire >> "</soapenv:Envelope>"  
 [2017-04-21 21:28:06,535] INFO - LogMediator STATUS = --------------------CheckXSLTEscapeCharacters Invoked--------------------  
 [2017-04-21 21:28:06,536] INFO - LogMediator To: /services/CheckXSLTEscapeCharacters, WSAction: urn:echoString, SOAPAction: urn:echoString, MessageID: urn:uuid:9813658e-ea39-48aa-9da4-d88e91ac087f, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org"><soapenv:Body>  
    <Description>Test for escaping &lt; > characters</Description>  
   </soapenv:Body></soapenv:Envelope>  
 [2017-04-21 21:28:06,537] INFO - LogMediator STATUS = --------------------CheckXSLTEscapeCharacters After Log full Invoked--------------------  
 [2017-04-21 21:28:06,543] INFO - LogMediator STATUS = --------------------CheckXSLTEscapeCharacters Invoked After XSLT Transformation--------------------  
 [2017-04-21 21:28:06,554] DEBUG - wire << "HTTP/1.1 200 OK[\r][\n]"  
 [2017-04-21 21:28:06,558] DEBUG - wire << "Host: ajanthan-ThinkPad-T440p:8280[\r][\n]"  
 [2017-04-21 21:28:06,559] DEBUG - wire << "SOAPAction: "urn:echoString"[\r][\n]"  
 [2017-04-21 21:28:06,559] DEBUG - wire << "Accept-Encoding: gzip,deflate[\r][\n]"  
 [2017-04-21 21:28:06,560] DEBUG - wire << "Content-Type: text/xml;charset=UTF-8; charset=UTF-8[\r][\n]"  
 [2017-04-21 21:28:06,560] DEBUG - wire << "Date: Fri, 21 Apr 2017 15:58:06 GMT[\r][\n]"  
 [2017-04-21 21:28:06,560] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"  
 [2017-04-21 21:28:06,560] DEBUG - wire << "Connection: Keep-Alive[\r][\n]"  
 [2017-04-21 21:28:06,560] DEBUG - wire << "[\r][\n]"  
 [2017-04-21 21:28:06,560] DEBUG - wire << "145[\r][\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org">[\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "  <soapenv:Header/>[\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "  <soapenv:Body>[\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "   <Description><![CDATA[Test for escaping < > characters]]></Description>[\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "  </soapenv:Body>[\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "</soapenv:Envelope>[\r][\n]"  
 [2017-04-21 21:28:06,561] DEBUG - wire << "0[\r][\n]"  
 [2017-04-21 21:28:06,562] DEBUG - wire << "[\r][\n]"  


No comments:

Post a Comment