I am attempting to make a blocking call that retrieves a PDF file, but an error is thrown whenever I try to use the returned payload (including sending it).
The error is "Attempted read on closed stream", and I think it's happening because the response is being parsed into xml only when it's needed, but by then the call mediator has closed the connection.
Here is an example sequence:
<call blocking="true">
<endpoint>
<http uri-template="https://myserver.com/generatePDF?id=1234" method="GET"/>
</endpoint>
</call>
<log level="custom">
<property name="msg" value="Complete"/>
</log>
<log level="custom">
<property name="body" expression="$body"/>
</log>
<log level="full"/>
Watching the logs, the call is made and it waits for the response. Once the response is completed the "Completed" log message is printed. But when it tries to access the $body the following error occurs:
[2016-05-19 13:03:21,582] INFO - LogMediator msg = Complete
[2016-05-19 13:03:21,584] ERROR - SequenceMediator Error reading data handler
org.apache.axiom.om.OMException: Error reading data handler
at org.apache.axiom.om.impl.llom.OMTextImpl.internalSerialize(OMTextImpl.java:421)
at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:555)
at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:875)
at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:555)
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.util.xpath.SynapseXPath.stringValueOf(SynapseXPath.java:321)
at org.apache.synapse.mediators.MediatorProperty.getEvaluatedExpression(MediatorProperty.java:138)
at org.apache.synapse.mediators.builtin.LogMediator.setCustomProperties(LogMediator.java:216)
at org.apache.synapse.mediators.builtin.LogMediator.getCustomLogMessage(LogMediator.java:139)
at org.apache.synapse.mediators.builtin.LogMediator.getLogMessage(LogMediator.java:125)
at org.apache.synapse.mediators.builtin.LogMediator.mediate(LogMediator.java:95)
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: java.io.IOException: Attempted read on closed stream.
at org.apache.commons.httpclient.AutoCloseInputStream.isReadAllowed(AutoCloseInputStream.java:183)
at org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:107)
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:238)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:116)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at org.wso2.carbon.relay.BinaryRelayBuilder.readAllFromInputSteam(BinaryRelayBuilder.java:39)
at org.wso2.carbon.relay.StreamingOnRequestDataSource.getInputStream(StreamingOnRequestDataSource.java:59)
at javax.activation.DataHandler.writeTo(DataHandler.java:305)
at org.apache.axiom.util.stax.XMLStreamWriterUtils.writeBase64(XMLStreamWriterUtils.java:62)
at org.apache.axiom.util.stax.XMLStreamWriterUtils.writeDataHandler(XMLStreamWriterUtils.java:138)
at org.apache.axiom.om.impl.llom.OMTextImpl.internalSerialize(OMTextImpl.java:418)
... 24 more
Stepping through the code I can see that the response is available on the http connection. An inputstream is built around that connection but after the call is complete the HTTP Connection is closed in the cleanup method.
When the body is first accessed, the stream is read but by then it's already closed, which gives the error below.
How can I retrieve a PDF using the call mediator with blocking="true"?
Details
WSO2 ESB 4.9.0
Added the following to the message builders section of axis2_blocking_client.xml
<messageBuilder contentType="application/pdf" class="org.wso2.carbon.relay.BinaryRelayBuilder" />