Mule - How to respond after receiving a request collection. (Mule Requester ) - exception

I am using the Mule Requestor to receive a collection of files via FTP.
In order to do this with a collection I am using the Collection Splitter which works great. The only problem is that when I am returning to the HTTP Connector it throws the following exception:
java.lang.UnsupportedOperationException: getPayloadAsBytes(), use
getPayload(DataType.BYTE_ARRAY_DATA_TYPE)
I am guessing this has something to do with the payload type that is trying to be inserted into the response, but I am fairly new in the Mule arena. Any idea what could be causing this and what I should do to resolve the issue?
I have tried setting the payload after the logger, that didn't work.
Code:
<flow name="fileGetter">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP" allowedMethods="GET"></http:listener>
<mulerequester:request-collection config-ref="Mule_Requester" resource="ftp_For_Requester_Dependent" doc:name="Mule Requester</mulerequester:request-collection>
<collection-splitter doc:name="Collection Splitter"></collection-splitter>
<logger level="INFO" doc:name="Logger" message="#[message.inboundProperties.originalFilename]"></logger>
</flow>

The reason you are getting java.lang.UnsupportedOperationException: getPayloadAsBytes(), use getPayload(DataType.BYTE_ARRAY_DATA_TYPE) is obvious, since you are splitting the payload, at the end your HTTP in causing the issue as there will be a split response .
One solution would be, use an aggregator at the end of your flow and that will prevent this exception.
A <collection-aggregator/> at the end will be a good choice and help to prevent this
UPDATE
Keep it under <async> block and it will run successfully

Related

How to reference a JSON example in set payload

I am using Anypoint Studio 6.1 and Mule 3.8.1 and have a JSON example in main/src/api called response-flow1.json. I want to set my payload to response-flow1.json if certain rules are met. How can I reference response-flow1.json in a Set Payload?
Thanks
To save the trouble of loading a file (Only if it's a small JSON), you can set your JSON payload in a variable in a properties file. Then call it like this:
<set-payload value="#[${samplejson}]" doc:name="Set Payload"/>
If this is not the answer you were looking for, please provide more information and I'll be glad to help. Thank you!
You can try the following: -
<set-payload value="#[Thread.currentThread().getContextClassLoader().getResourceAsStream('response-flow1.json')]" doc:name="Set Payload"/>
Best practice will be keeping the response-flow1.json under resource folder
We have the option to use the dataweave:
<set-payload value="#[dw('readUrl("classpath://examples/filename.json","application/json")')]" doc:name="Set Mock Payload"/>

How can i preserve the payload in Mule when an Exception is caught?

I have used a "catch exception strategy" to catch any exception that arise in the flow. Now i want to print the payload just before which the exception has araised . Is there a way to achieve this in mule?
Store the payload in session variable and print that in catch exception strategy.
You can get the exception Payload from the MuleMessage using message.getExceptionPayload() but, when an exception occurs the payload is consumed and in order to get the original payload that was before the exception you'll have to resort to the storing of payload in a variable like <set-variable variableName="originalPayload" value="#[message.payload]" /> and then access it using MEL #[flowVars.originalPayload] after the exception has occured (or using message.getInvocationProperty("originalPayload") if you're inside a JAVA component).
Here are some links for your reference though that'll shed more light into the topic :
https://docs.mulesoft.com/mule-user-guide/v/3.6/exception-strategy-most-common-use-cases
Why is Mule payload getting lost in <catch-exception-strategy> for java.net.ConnectException
Mule ESB - Catch Exception Strategy block and Payload
You can use session scope for the variable so that it doesn't get lost.
-Shanky G.
you can try this as follows by dragging "catch exception stratergy"
<catch-exception-strategy doc:name="Catch_Exception_Strategy">
<logger message="Exception---" level="INFO" doc:name="Logger"/>
<set-variable variableName="SetException" value="#[exception.message]" doc:name="SetException"/>
<set-payload value="#[payload]" doc:name="FailedToEvaluateTheTask"/>
</catch-exception-strategy>
Hope this helps you out!

Mule Collection aggregator

I am trying to use Mule 3.2.0 s Collection Aggregator. I tried using Mule Studio but seems it is still not available in Mule studio for configuration though the icon does appear in the "Flow Control" section.
My use case is -
I get a message from a VM Inbound endpoint. I now want to pass that to 3 different flows - all using the same request object but performing different operations - say A,B,C. All of them update their respective databases but they are all part of a common Order_ID(somethig internal to our application). The 3 processes may take different processing times but once done each of them return the same success response. I want to use an aggregator which will aggregate all these responses without timing out and then forward that to a Java component or another VM Endpoint for further processing.
The Mule documentation for Collection Aggregator doesn't seem to be very informative so if some one who has used Collection Agg can help me out with the xml config for the above scenario it will be very helpful
Instead of Collection Aggregator use All message processor. It sends the same message to every processor inside it and aggregates the results after they finish.
http://www.mulesoft.org/documentation/display/MULE3USER/Routing+Message+Processors#RoutingMessageProcessors-All
Sample config: (I send "foo" to the vm endpoint)
<flow name="main" processingStrategy="asynchronous">
<vm:inbound-endpoint path="in"/>
<all>
<flow-ref name="flow1"/>
<flow-ref name="flow2"/>
</all>
<logger message="#[payload:]" level="INFO"/>
</flow>
<flow name="flow1">
<append-string-transformer message="bar1"/>
</flow>
<flow name="flow2">
<append-string-transformer message="bar2"/>
</flow>
Console output:
INFO 2012-08-15 17:26:01,749 [main.stage1.02] org.mule.api.processor.LoggerMessageProcessor: [foobar1, foobar2]
HTH
I would go with to use ALL component and the endpoint you use should be request-response (two-way where the flow waits for the response).
Thus the ALL component will aggregate the response an then returns you a CopyOnWriteArrayList with all the response from the flows A,B and C. This Array list you can transform in any desired way using a custom transformer by extending AbstractTransformer in your java class.
Cheers,
Naveen Raj

Message relay for JSON data in wso2ESB

I am trying to build a simple POC using wso2ESB. I've created a simple pass through proxy service with an Alfresco service http://www.alfresco.com/
The problem is I am not getting the full JSON data. I've read it has something to do with the axis2-JSON and that it causes problems when one has JSONArray in the root. So I've decided to use message relay.
WSO2 ESB Unable to convert complete JSON data to XML
I've edited the axis2.xml as described in the documentation thus adding the following lines
<messageFormatter contentType="application/json"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
and
<messageBuilder contentType="application/xml"
class="org.apache.axis2.builder.ApplicationXMLBuilder"/>
But after I've restarted the server when I try to use the proxy server through the firefox REST plugin the ESB throws the following exception
[2012-07-12 10:02:29,125] WARN - ClientWorker Unexpected response received. HTTP response co
de : 405 HTTP status : Method Not Allowed exception : SOAP message MUST NOT contain a Documen
t Type Declaration(DTD)
[2012-07-12 10:02:29,125] ERROR - NativeWorkerPool Uncaught exception
java.lang.ClassCastException: org.apache.axiom.om.impl.llom.OMTextImpl cannot be cast to org.
apache.axiom.om.OMElement
at org.apache.synapse.util.MessageHelper.cloneSOAPFault(MessageHelper.java:441)
at org.apache.synapse.util.MessageHelper.cloneSOAPEnvelope(MessageHelper.java:254)
at org.apache.synapse.core.axis2.SOAPUtils.convertSOAP11toSOAP12(SOAPUtils.java:95)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbac
kReceiver.java:323)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackRecei
ver.java:160)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
at org.apache.synapse.transport.nhttp.ClientWorker.run(ClientWorker.java:275)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.ja
va:173)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886
)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
What causes this? Is the problem that ESB still tries to convert the JSON object instead of trying to relay it?
Is there another workaround in parsing these JSON objects (i.e. adding artificial root to the JSON object?)
at the builders you need to set the application/json to use org.wso2.carbon.relay.BinaryRelayBuilder as well.

In Spring 3.0.5 and coding it to serve JSON, what is this log output trying to tell me?

Using Spring 3.0.5, I am trying to return a list of strings in JSON format.
I read the post spring-mvc-json-response
I have available to me jackson-mapper code 1.4.2 and it's on my classpath.
I am also using <context:component-scan base-package="com.funfun.foofoo2" /> which should satisfy the <mvc:annotation-driven> requirement.
I am returning a List<String> although I have tried just a bean too.
When I return raw JSON as a String, it works.
What is the following log output telling me? Is it saying it cannot find the Jackson JSON Mapper and thus the MappingJacksonHttpMessageConverter is not loaded?
17:19:01,037 DEBUG [AnnotationMethodHandlerExceptionResolver:132] Resolving exception from handler [com.funfun.foofoo2.CarModelsController#181fa4b]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
17:19:01,037 DEBUG [ResponseStatusExceptionResolver:132] Resolving exception from handler [com.funfun.foofoo2.CarModelsController#181fa4b]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
17:19:01,037 DEBUG [DefaultHandlerExceptionResolver:132] Resolving exception from handler [com.funfun.foofoo2.CarModelsController#181fa4b]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
17:19:01,053 DEBUG [DispatcherServlet:824] Null ModelAndView returned to DispatcherServlet with name 'appServlet': assuming HandlerAdapter completed request handling
Update: I am using jQuery's getJSON. In Firefox Firebug, I see the header coming over as application/json. The Spring method is constrained to only handle requests for JSON.
You need more than jackson-mapper, you need jackson-core as well, and preferably something newer than the rather old 1.4.x versions.
Basically what this exception (HttpMediaTypeNotAcceptableException) means is that the client is specifying an accepts header in their HTTP request, and it likely isn't accepting JSON. How are you making this request? AJAX call? If so, use Firebug or something to inspect the XHR and see what the accepts header is set to.
Just check the Accept param in your HTTP request header. If you are using XMLHttpRequest to make the ajax call, don't forget to change the requestHeader as follow:
xmlhttp.open("POST", custom_url, this.async);
xmlhttp.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml,application/json;q=0.9,*/*;q=0.8");
Regards,
David.