Mule requester in a MUnit Test case - mule

I have to use a Mule Requester Inside MUnit test case to read a file under src/test/resources so that i can assert the payload . With the current implementation I have Ftp connector inside MUnits xml which I am referring from mule requester . I clearly see that mule requester is trying to access the connector even before it it initialized . Is there any way i can tell mule to early intialize ftp connector ?
Exception :
********************************************************************************
Message : Cannot perform an action on a connector when it is not started. Connector "no-delete-file-connector-test" is currently in lifecycle phase "initialise"
Element : /no-delete-file-connector-test # app:haz001-test-suite.xml:33 (File)
--------------------------------------------------------------------------------
Exception stack is:
Cannot perform an action on a connector when it is not started. Connector "no-delete-file-connector-test" is currently in lifecycle phase "initialise" (org.mule.api.lifecycle.LifecycleException)
org.mule.transport.AbstractConnector.getRequester(AbstractConnector.java:1178)
org.mule.transport.AbstractConnector.request(AbstractConnector.java:2269)
org.mule.transport.file.FileConnector$$EnhancerByCGLIB$$d6c65eff.CGLIB$request$75(<generated>:-1)
(97 more...)
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Following is my configuration :
<flow-ref name="processMainFlow" doc:name="processMainFlow" />
<mulerequester:request resource="file://src/test/resources/expected-discrete.csv?connector=no-delete-file-connector-test" doc:name="Mule Requester" returnClass="java.lang.String"/>
<munit:assert-payload-equals expectedValue="#[flowVars.outputCSV]" doc:name="Assert Payload"/>
<logger message="response for test #[payload] actual data : #[flowVars.outputCSV]" level="INFO"
doc:name="Logger" />

To load a file in your Munit test, you don't need the file connector, use a Set Payload or Set Message, eg:
<set-payload value="#[getResource('expected-discrete.csv').asStream()]" doc:name="Set Payload"/>
The path inside getResource is relative to testResources specified in your pom file (defaults to src/test/munit and src/test/resources).
The file connector is stopped because that is the default behaviour of connectors in Munit tests. There is more info about this in the Mulesoft forums: https://forums.mulesoft.com/questions/44649/munit-config-mock-inbounds-mock-connectors.html

Try to mock the component instead of calling it. If mocked it can avoid this error since FTP requires initiation which is not possible in munit.

Related

Mule 4 sftp read file - reconnection strategy not working

Am trying to read a file from a SFTP location .
Am using Mule 4.4 Community edition.
If there is any error while connecting to SFTP server or file is not present , would like mule to retry 2 times .
So I configured in sftp connector : 'Reconnection strategy' as 'Standard'
However the logs do not show any retry occurring .
NOTE - ideally this will be kicked off at a scheduled time ( scheduler ) but for purposes of testing am using a HTTP Listener to invoke the flow
Here is the code :
<sftp:config name="SFTP_Config" doc:name="SFTP Config">
<sftp:connection host="abcd" username="xyz" password="pwd" />
</sftp:config>
<flow name="get:employee">
<logger level="INFO" doc:name="Logger" message="starting search" category="get-employee"/>
<sftp:read doc:name="Read" config-ref="SFTP_Config" path="/a/employees.unl">
<repeatable-in-memory-stream />
<reconnect />
</sftp:read>
<error-handler ></error-handler>
</flow>
Am wondering if I am doing something wrong ? I would want the flow or atleast the file reading to be attempted twice before erroring out.
Presently when the file does not exist in the sftp location it simply throws an error :
Message : Path '/a/employees.unl' doesn't exist
Error type : SFTP:ILLEGAL_PATH
when does the reconnection strategy kick in ?
Thanks
Reconnection strategies are for connections, not operations that fail. In your example the connection is working ok. The operation fails because the directory doesn't exists.
For an operations you should put the operation inside an <until-successful> scope. You can use the maxRetries attribute to specify the number of retries.
Documentation: https://docs.mulesoft.com/mule-runtime/4.4/until-successful-scope

Vars are getting wiped off while using vm connector in mule 4

mule doc says they have removed transport barrier so there is no need to have session vars in mule 4. when I am using a VM connector to publish and consume using VM vars are getting wiped off. I did cross check with mule 3.9 session vars will be persisted after reaching other flow irrespective of configured VM is one-way to req-res.
<vm:config name="vm">
<vm:queues>
<vm:queue queueName="publish" />
</vm:queues>
</vm:config>
<flow name="persistentVM">
<vm:listener queueName="publish" config-ref="vm"
numberOfConsumers="1">
<vm:response>
<vm:content><![CDATA[
]]></vm:content>
</vm:response>
</vm:listener>
<logger level="INFO" doc:name="Logger"
doc:id="1d624aa2-0aa4-4c5d-a258-0a8135a792ff" message="#[vars.test]" />
</flow>
<flow name="publish">
<http:listener doc:name="Listener"
doc:id="68f9601d-d31e-4de6-a448-98a43724de42" config-ref="HTTP_Listener_config"
path="/error" />
<set-variable value="#['My Message']" doc:name="Set Variable"
doc:id="861cc914-b1ad-4068-8753-a0fd1915bed4" variableName="test" />
<vm:publish doc:name="Publish" doc:id="153209cb-49f2-4f80-8305-56dcd046aa3c" config-ref="vm" queueName="publish"/>
`
Any comments on this is much helpful.
For Mule 4 session vars are removed and vars will not propagate across transport barriers. If you want the var in the other flow, you will either have to make it part of the payload and publish it using vm:content, persist it using the ObjectStore or use flows and flow-ref instead of the vm connector.

Mulesoft connection timeout issue

I'm getting a Connect timeout exception when I try to run a simple mule flow:
Message : Error sending HTTP request. Payload
: {NullPayload} Payload Type : org.mule.transport.NullPayload
Element : /getunitedflightsFlow/processors/0 #
getunitedflights:getunitedflights.xml:15 (Get Flights Requests)
Element XML :
Root Exception stack trace: java.net.ConnectException: Connect timeout
at
org.glassfish.grizzly.connectionpool.SingleEndpointPool$ConnectCompletionHandler.cancelled(SingleEndpointPool.java:1284)
at
org.glassfish.grizzly.impl.SafeFutureImpl.notifyCompletionHandlers(SafeFutureImpl.java:185)
at
org.glassfish.grizzly.impl.SafeFutureImpl.done(SafeFutureImpl.java:277)
at
org.glassfish.grizzly.impl.SafeFutureImpl$Sync.innerCancel(SafeFutureImpl.java:389)
at
org.glassfish.grizzly.impl.SafeFutureImpl.cancel(SafeFutureImpl.java:247)
at
org.glassfish.grizzly.connectionpool.SingleEndpointPool$ConnectTimeoutWorker.doWork(SingleEndpointPool.java:1352)
at
org.glassfish.grizzly.connectionpool.SingleEndpointPool$ConnectTimeoutWorker.doWork(SingleEndpointPool.java:1344)
at
org.glassfish.grizzly.utils.DelayedExecutor$DelayedRunnable.run(DelayedExecutor.java:158)
at
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:748)
Here is the Mule flow:
<flow name="getunitedflightsFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/home" doc:name="HTTP"/>
<http:request config-ref="HTTP_Request_Configuration" path="/essentials/united/flights" method="GET" doc:name="Get Flights Requests"/>
</flow>
I did some googling and it looks like a proxy/firewall issue, I tried adding the proxy settings under preferences and all Native/Direct/Manual options won't work. I also added the following properties/args:
-XX:PermSize=128M -XX:MaxPermSize=256M -Dhttps.proxyHost=proxy.xxxx.com -Dhttps.proxyPort=8080 -Dhttps.proxyUsername=myfirst.mylast -Dhttps.proxyPassword=xxxxxxxxx
it doesn't work, also tried changing the proxy settings in the Http request connector itself but this doesn't work either.
Does anyone know what's going on here,
your help is appreciated!

Mule SQS sendMessage throwing Failed to transform from "json" to "java.util.HashMap"

After upgrading to latest SQS connector previously working code now fails.
Mule ESB and Integration Platform Version: 3.6.0 Build: ed775fdb
Amazon SQS Connector (Mule 3.5.0+) 3.0.0.201506091134
The latest version of the connector requires the message attribute to be specified.
API doc's show message should be a String.
http://mulesoft.github.io/sqs-connector/3.0.0/mule/sqs-config.html#send-message
Using:
<object-to-string-transformer doc:name="Object to String"/>
The flow takes the posted data and submits it as a SQS message.
<flow name="rxWebhook">
<http:listener config-ref="HTTPS_8081" path="/" doc:name="HTTPS" responseStreamingMode="ALWAYS">
<http:response-builder disablePropertiesAsHeaders="true"/>
</http:listener>
<object-to-string-transformer doc:name="Object to String"/>
<sqs:send-message config-ref="Amazon_SQS_USWEST2" message="#[payload]" queueUrl="${aws.sqs.myQueue}" doc:name="Amazon SQS"/>
</flow>
When posting json data to the flow it errors with:
org.mule.api.transformer.TransformerMessagingException: Failed to transform from "json" to "java.util.HashMap". Message payload is of type: String
I think it's because theres i an optional parameter named:
<sqs:message-attributes>
Which defaults to #[payload] and expects the payload to be a Map. So to avoid this, specify the param and try passing null maybe:
<sqs:send-message config-ref="Amazon_SQS_USWEST2" message="#[payload]" queueUrl="${aws.sqs.myQueue}" doc:name="Amazon SQS">
<sqs:message-attributes ref="#[null]"/>
</sqs:send-message>

Read messages from different SQS queues in Mule

I have 2 separate Amazon SQS queues; Queue and ResponseQueue.
SQS configurations:
<sqs:config name="Amazon_SQS_Consumer" accessKey="XXX" secretKey="XXX" queueName="Queue" doc:name="Amazon SQS">
<sqs:connection-pooling-profile maxActive="10" maxIdle="10" exhaustedAction="WHEN_EXHAUSTED_GROW" maxWait="12000" minEvictionMillis="60000" evictionCheckIntervalMillis="30000" initialisationPolicy="INITIALISE_ONE"/>
<reconnect count="5" frequency="1000"/>
</sqs:config>
<sqs:config name="Amazon_SQS_Response" accessKey="XXX" secretKey="XXX" queueName="ResponseQueue" doc:name="Amazon SQS">
<sqs:connection-pooling-profile maxActive="100" maxIdle="10" exhaustedAction="WHEN_EXHAUSTED_GROW" maxWait="12000" minEvictionMillis="60000" evictionCheckIntervalMillis="30000" initialisationPolicy="INITIALISE_ONE"/>
<reconnect count="5" frequency="1000"/>
</sqs:config>
I have no problem receiving messages from the first queue (Queue) via:
<flow name="consumer" doc:name="consumer">
<sqs:receive-messages config-ref="Amazon_SQS_Consumer" preserveMessages="true" doc:name="Amazon SQS (Streaming)" visibilityTimeout="300" />
<logger level="INFO" message="#[payload]" />
</flow>
I need to also receive messages from the second queue (ResponseQueue):
<flow name="response" doc:name="response">
<sqs:receive-messages config-ref="Amazon_SQS_Response" preserveMessages="true" doc:name="Amazon SQS (Streaming)" visibilityTimeout="300" />
<logger level="INFO" message="#[payload]" />
</flow>
However, whenever the second sqs:receive-messages is added, I get the following error:
Exception in thread "Receiving Thread" java.lang.LinkageError: loader (instance of org/mule/module/launcher/plugin/MulePluginsClassLoader): attempted duplicate class definition for name: "com/amazonaws/services/sqs/QueueUrlHandler"
Is it possible to read messages from 2 different queues in the same project?
I'm using 3.4.0 CE Mule Server Runtime and 2.4.4 Amazon SQS Connector. I need to stay at these versions. If I switch to 3.5.0 EE Mule Server Runtime, there is no problem in having multiple sqs:receive-messages; it works just as expected. However, it leads to another issue.
Are you using the same credentials in both sqs:config elements? If yes, then you only need one config element and then specify the queue name on the sqs:receive-messages elements.
<sqs:receive-messages queueName="Queue"
preserveMessages="true"
visibilityTimeout="300" />
Refer to the user guide: http://mulesoft.github.io/sqs-connector/2.5.0/mule/sqs-config.html#receive-messages