I use Mule ESB version 3.5.0
I set up a project in Anypoint Studio containing a flow that accepted requests using an http:inbound-endpoint, added a SOAP header to the body and forwarded it to an external web application. I used the graphical user interface and that worked great. The xml that was generated is the following:
<flow name="Online_Service" doc:name="Online_Service">
<http:inbound-endpoint exchange-pattern="request-response" name="clientEndpoint" address="http://localhost:1234/in" doc:name="HTTP" contentType="text/xml"/>
<component doc:name="SOAP Header Creator">
<spring-object bean="SoapHeaderCreatorBean"/>
</component>
<file:outbound-endpoint path="C:/mule/Online/OUT" responseTimeout="10000" doc:name="Requests"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/spring-webservices-sample/endpoints" doc:name="HTTP" method="POST" contentType="text/xml"/>
<file:outbound-endpoint path="C:/mule/Online/OUT" responseTimeout="10000" doc:name="Responses"/>
</flow>
Then, the need arised to package the mule application as a war in order to deploy it on a Tomcat application server. I managed to create the war and flows that readed from the filesystem instead of an HTTP endpoint work great. After reading through the documentation, I discovered that the HTTP endpoint can not be used in a servlet context and I adapted my flow to this one:
<flow name="onlineService" processingStrategy="synchronous">
<servlet:inbound-endpoint path="/in" responseTimeout="10000" />
<component>
<spring-object bean="SoapHeaderCreatorBean"/>
</component>
<file:outbound-endpoint path="C:/mule/Online/Requests" responseTimeout="10000"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/spring-webservices-sample/endpoints" method="POST" contentType="text/xml"/>
<file:outbound-endpoint path="C:/mule/Online/Responses" responseTimeout="10000"/>
</flow>
However now, if I send some content to the servlet, I receive following exception:
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:126)
at org.mule.model.streaming.DelegatingInputStream.read(DelegatingInputStream.java:54)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
at org.mule.transformer.simple.ObjectToOutputHandler$3.write(ObjectToOutputHandler.java:72)
at org.mule.transport.servlet.AbstractReceiverServlet.writeResponseFromMessage(AbstractReceiverServlet.java:185)
at org.mule.transport.servlet.AbstractReceiverServlet.writeResponse(AbstractReceiverServlet.java:157)
at org.mule.transport.servlet.MuleReceiverServlet.doAllMethods(MuleReceiverServlet.java:246)
at org.mule.transport.servlet.MuleReceiverServlet.doPost(MuleReceiverServlet.java:194)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.mule.transport.servlet.MuleReceiverServlet.service(MuleReceiverServlet.java:176)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at com.googlecode.psiprobe.Tomcat70AgentValve.invoke(Tomcat70AgentValve.java:38)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
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)
I tried to add a:
<object-to-string-transformer />
component after the servlet definition but that doesn't seem to help...
I found the problem: The http:outbound-endpoint is giving a stream and the file:outbound-endpoint is consuming this. I've put a transformer (object-to-string) after the HTTP outbound endpoint and this solves my issue:
<flow name="onlineService" processingStrategy="synchronous">
<servlet:inbound-endpoint path="/in" responseTimeout="10000" />
<component>
<spring-object bean="SoapHeaderCreatorBean"/>
</component>
<file:outbound-endpoint path="C:/mule/Online/Requests" responseTimeout="10000"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/spring-webservices-sample/endpoints" method="POST" contentType="text/xml"/>
<object-to-string-transformer/>
<file:outbound-endpoint path="C:/mule/Online/Responses" responseTimeout="10000"/>
</flow>
Like this, the stream is stored in memory and not consumed before the response is returned to the HTTP inbound endpoint.