In this flow the HTTP inbound is configured with request-response. But I still dont get the response as it is routed to the File outbound. How do I get a response for the HTTP endpoint and also route the response to File outbound.
<flow name="helloFlow1" doc:name="helloFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9095" doc:name="HTTP"/>
<custom-transformer class="com.uk.MyTransformer" doc:name="Java"/>
<component class="com.uk.MyComponent" doc:name="Java"/>
<echo-component doc:name="Echo"/>
<file:outbound-endpoint path="C:\" outputPattern="file#[function:datestamp]" doc:name="File"/>
You don't receive a response because nothing creates one: the file:outbound-endpoint is one-way per nature and doesn't generate a response event.
Assuming you want the same content written to the file to be also returned to the caller of the HTTP endpoint, one option consists in "detaching" the writing to the file in a parallel async flow so the main flow returns its current value to the caller:
<flow name="helloFlow1" doc:name="helloFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9095" doc:name="HTTP"/>
<custom-transformer class="com.uk.MyTransformer" doc:name="Java"/>
<component class="com.uk.MyComponent" doc:name="Java"/>
<echo-component doc:name="Echo"/>
<async>
<file:outbound-endpoint path="C:\" outputPattern="file#[function:datestamp]" doc:name="File"/>
</async>
</flow>
Related
I have a case where I need to poll a directory on my file system. Each file that is added to that directory needs to be posted to an HTTP endpoint.
The HTTP endpoint is available on "/rest/latest/file". Using postman, I've verified that the REST call works with the following settings:
POST
basic auth
form-data:
key = file
value = Selected a file from my file system (using a dialog)
My mule flow currently looks like this:
<file:connector name="File" autoDelete="true" streaming="true" validateConnections="true" moveToPattern="#[message.inboundProperties['originalFilename']].backup" moveToDirectory="src/main/resources/output" doc:name="File"/>
<flow name="importdataqualityresultsFlow1" doc:name="importdataqualityresultsFlow1">
<file:inbound-endpoint path="src/main/resources/input" responseTimeout="10000" doc:name="File"/>
<set-payload value="#[['file' :#[message.inboundAttachments['text.txt']]]]" doc:name="Set Payload"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="80" path="rest/latest/file" method="POST" user="Admin" password="admin" contentType="application/form-data" doc:name="HTTP"/>
</flow>
I can tell in my application logs that the user logs in using basic auth, after which I get a stack trace.
Any help / pointers would be greatly appreciated.
You need to create a map payload with the form fields:
<flow name="importdataqualityresultsFlow1">
<file:inbound-endpoint path="src/main/resources/input" />
<object-to-string-transformer />
<set-payload value="#[['file': message.payload]]" />
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="80" path="rest/latest/file" method="POST" user="Admin" password="admin" contentType="application/form-data" />
</flow>
I actually invoke an exe with the expression-component through a http-request on port 8081. The exe sends a http-request on port 8082 and I'm able to log the output.
Finally i have to send the output of the reply-flow back to the main-flow but i dont know how...
Here is my code:
<flow name="mainFlow" doc:name="mainFlow">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:8081" doc:name="HTTP" />
<request-reply timeout="10000">
<vm:outbound-endpoint path="request" exchange-pattern="one-way"/>
<vm:inbound-endpoint path="reply" exchange-pattern="one-way"/>
</request-reply>
</flow>
<flow name="request" doc:name="request">
<vm:inbound-endpoint path="request" doc:name="VM" />
<expression-component doc:name="Expression">Runtime.getRuntime().exec("C:\\myfile.exe arg1");</expression-component>
</flow>
<flow name="reply" doc:name="reply">
<http:inbound-endpoint address="http://localhost:8082" doc:name="HTTP" exchange-pattern="one-way" />
<logger message="#[message.inboundProperties['test']]" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint path="reply" doc:name="VM" exchange-pattern="one-way"/>
</flow>
You have to make sure you are carrying the MULE_CORRELATION_ID message property through the exe down to http://localhost:8082 otherwise the request-reply message processor has no way to correlate the asynchronous reply with the current request.
For example, pass the correlation ID has a second argument to the exe:
<expression-component doc:name="Expression">
Runtime.getRuntime().exec("C:\\myfile.exe arg1 " + message.correlationId);
</expression-component>
And make sure the exe propagates the correlation ID towards http://localhost:8082 in an HTTP header named X-MULE_CORRELATION_ID.
When i make a call to to soap web service using the soap component in Mule. The message properties context is lost. I understand a Mule enricher component can be used but not sure on the usage. Below you will find my test mule code
<spring:beans>
<spring:bean id="myWebServiceImpl" class="com.xxx.xxx.service.MyWebServiceImpl">
</spring:bean>
</spring:beans>
<custom-transformer class="com.xxx.xxx.service.TestTransformer" name="Java" doc:name="Java"/>
<flow name="testwebserviceFlow1" doc:name="testwebserviceFlow1">
<file:inbound-endpoint path="c:\landing" responseTimeout="10000" doc:name="File"/>
<object-to-string-transformer doc:name="Object to String"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:28081/MyWebService" responseTimeout="100000" doc:name="HTTP" >
<cxf:jaxws-client operation="helloWorld" serviceClass="com.xxx.xxx.service.MyWebService" enableMuleSoapHeaders="true" doc:name="SOAP"/>
</http:outbound-endpoint>
<transformer ref="Java" doc:name="Transformer Reference"/>
<logger level="INFO" doc:name="Logger"/>
</flow>
<flow name="MyWebServiceFlow" doc:name="MyWebServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:28081/MyWebService?wsdl" doc:name="HTTP" responseTimeout="100000">
<cxf:jaxws-service serviceClass="com.xxx.xxx.service.MyWebService" doc:name="SOAP"/>
</http:inbound-endpoint>
<component doc:name="MyWebService">
<spring-object bean="myWebServiceImpl"/>
</component>
</flow>
Yes, you can use an enricher to preserve your original message and put the return value of the web service into a variable. It works like this:
<enricher source="#[payload]" target="#[variable:myVal]">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:28081/MyWebService" responseTimeout="100000" doc:name="HTTP" >
<cxf:jaxws-client operation="helloWorld" serviceClass="com.xxx.xxx.service.MyWebService" enableMuleSoapHeaders="true" doc:name="SOAP"/>
</http:outbound-endpoint>
</enricher>
You can then later access the variable like this:
<logger message="#[variable:myVal]" level="INFO"/>
If you just want to call the web service and ignore any return values, you can also do that asynchronously by putting the http outbound inside <async></async> tags instead of the enricher.
Is there a way to send the JSON response to another server as a request asynchronously (for example to monitor, etc...)
here is my mule flow
<flow name="loggingFlow1" doc:name="loggingFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="${source.http.host}" port="${source.http.port}" doc:name="HTTP" responseTimeout="10000" />
<http:outbound-endpoint exchange-pattern="request-response" method="GET" address="http://${dest.http.host}:${dest.http.port}#[header:INBOUND:http.request]" contentType="application/json" doc:name="HTTP_GET" responseTimeout="10000" />
<async processingStrategy="Asynchronous_Processing_Strategy" doc:name="Async">
<http:outbound-endpoint exchange-pattern="one-way" address="http://localhost:8080/Monitor/response" doc:name="HTTP"/>
</async>
</flow>
For any reason, it seems the InputStream produced by the first http:outbound-endpoint is read more than once.
Serializing this InputStream to a String with an object-to-string-transformer or a byte[] with an object-to-byte-array-transformer is the best option, the echo-component is a legacy one that is not very much used anymore.
I am attempting to consume a wsdl service using cfx:proxy-client in Mule ESB 3.3 but keep getting this error
org.apache.cxf.service.factory.ServiceConstructionException: Could not find definition for service {http://support.cxf.module.mule.org/}ProxyService.
at org.apache.cxf.wsdl11.WSDLServiceFactory.create(WSDLServiceFactory.java:139)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromWSDL(ReflectionServiceFactoryBean.java:383)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:506)
Below is my simple flow:
<flow name="spider-middleware" doc:name="spider-middleware">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="salesforce" doc:name="HTTP"/>
<cxf:proxy-client operation="getCustomerByID"
payload="body"
wsdlLocation="http://localhost:4546/eplus-ws-fake/services/EplusCustomer/v1?wsdl"
enableMuleSoapHeaders="true"
doc:name="SOAP"/>
</flow>
The service is hardcoded to return a customer for getCustomerByID(1).
Please shed some lights on how do I get around the issue?
Thanks.
I got it working but only by providing a full SOAP envelope and not just the body, ie. using payload="envelope".
Also I removed the operation and wsdlLocation attributes, which are useless for the proxy-client. I also had to add SOAPAction and Content-Type properties, otherwise the test webservice I'm using chokes on the request.
This gives (using a test service from WebServiceX.net):
<flow name="pureCxfProxyClient">
<vm:inbound-endpoint path="test.in"
exchange-pattern="request-response" />
<set-property propertyName="SOAPAction"
value="http://www.webservicex.net/getACHByZipCode" />
<set-property propertyName="Content-Type" value="text/xml" />
<http:outbound-endpoint address="http://www.webservicex.net/FedACH.asmx"
exchange-pattern="request-response" >
<cxf:proxy-client payload="envelope" />
</http:outbound-endpoint>
</flow>
Note I used a VM endpoint, which allowed me to deal with the XMLStreamReader returned by the cxf:proxy-client.
In particular, I needed to do the following:
final XMLStreamReader xsr = (XMLStreamReader) result.getPayload();
xsr.nextTag();
to avoid crazy NPEs in org.mule.module.xml.stax.ReversibleXMLStreamReader.
All in all this is pretty intense... plus the cxf:proxy-client doesn't deliver much value when used standalone. You could actually just go with:
<flow name="pureCxfProxyClient">
<vm:inbound-endpoint path="test.in"
exchange-pattern="request-response" />
<set-property propertyName="SOAPAction"
value="http://www.webservicex.net/getACHByZipCode" />
<set-property propertyName="Content-Type" value="text/xml" />
<http:outbound-endpoint address="http://www.webservicex.net/FedACH.asmx"
exchange-pattern="request-response" />
</flow>
... and be freed of the XMLStreamReader part.