How to mock http connectors in munit - mule

We are having our custom http connector and an outbound which refers to that connector as follows
<http:connector name="myConnector">
<!-- config -->
</http:connector>
<http:endpoint name="myEndpoint" ref="myConnector">
<!-- config -->
</http:endpoint>
<http:outbound-endpoint name="myOutbound" ref="myEndpoint">
When I am mocking http outbound without specifying any attributes then its mocking .But if I am using mock while specifying attributes then it is throwing exception saying
"cannot process event as myConnector has stopped working".

By default munit will stop the connector, and if you're seeing that message it means your not hitting the correct mocked endpoint. I would check that the attributes correctly match. Can you post your mock configuration and your endpoint configuration? So a better answer can be provided.
You can mock endpoints the same was as any message processor:
whenMessageProcessor("outbound-endpoint").ofNamespace("http").thenReturnSameEvent()
As a side note if you don't want the connector to be stopped by default you can override haveToMockMuleConnectors from FunctionalMunitSuite:
#Override
public boolean haveToMockMuleConnectors() {
return false;
}
But then you won't hit the mocked endpoint.

Related

Logging of Client Side error in Mule flows

How to handle or log the client side error in best way. Say for Client enters the URL and he received 501 error. We need to log that error as well we need to log from which api call that error was occurred.
Can someone suggest. sorry, I cant give a example because its generic doubt in my mind
If any one suggests how to do. I will create the flow will share here for public use
You can't capture the HTTP status that the HTTP Listener sends automatically. For example a 404 (page not found), if there is no listener for that URL.
You can capture your own HTTP status that you set in your application, and do something before the flow ends.
Example:
<flow name="statusFlow" >
<http:listener doc:name="Listener" config-ref="HTTP_Listener_config" path="/page">
<http:response statusCode="#[vars.okStatus]" />
<http:error-response statusCode="#[vars.errorStatus]" />
</http:listener>
... set the variables ...
... log the variables ...
Note that the application can not know about status returned by something in front of your application, like a load balancer. That's the case for applications deployed to CloudHub and accessed through the load balancer.

Unable to Pull Message off Queue

Let me explain my configuration:
ActiveMQ 5.12.0
AnyPoint Studio 5.2.1
Mule 3.6.1
Flow of application:
I am using FunctionalTestCase to post and retrieve a message from queue.
MuleClient client = muleContext.getClient();
String productAsJson = "{\"name\":\"Widget\", \"price\":9.99, \"weight\":1.0, \"sku\":\"abcd-12345\"}";
client.dispatch("http://localhost:8081/products", productAsJson, null);
MuleMessage result = client.request("jms://products", RECEIVE_TIMEOUT);
What is happening is the message is getting posted but when I try to retrieve it, I get the string "{NullPayLoad}".
After stepping back through the flow, I have discovered the message payload, when using the Mule Client, is not making the queue. While looking through the admin console for ActiveMQ, I discovered the message details is "{NullPayload}". When I check using the Advance Risk Client, the JSON message is getting posted correctly.
Any suggestions would be greatly appreciated.
Russ
It's NullPayload when using the MuleClient because by default the http operation will be GET and wont be expecting a body to parse.
The MuleClient is more suited to working with Mule transport infrastructure such as the JMS transport or the old http transport. I don't think it plays nice with the new http listener module.
Normally with the transports you can set the method via a property but that doesnt seem to work with the http:listener:
MuleMessage message = getTestMuleMessage();
message.setPayload(productAsJson);
message.setProperty("http.method", "POST", PropertyScope.INBOUND);
client.send("http://localhost:8089/products", message);
I would suggest using a standard HTTP client such as Apache HTTP client etc. and set the method to POST/PUT or whatever method you need to use that expects a body.

Mule : No receiver found on secondary lookup of receiver on connector: HTTP_HTTPS with URI key: https://myhost:443/robots.txt

I have these warnings filling all my logs. It seems to be caused by crawlers and spiders http://www.robotstxt.org/
No receiver found on secondary lookup of receiver on connector: HTTP_HTTPS with URI key: https://myhost:443/robots.txt.
org.mule.transport.http.HttpsConnector: Receivers on connector are: {
I cannot find anyone who had this issue on the web before me...
I want to get rid of it in my flow, how can I do that? I can share the code but I don't see how it is relevant in this case.
Thanks.
The issue you're having can be reproduced through the following steps:
Add an inbound endpoint that has the following url: http://localhost:8081/test, start your app and call http://localhost:8081/something.txt
The explanation is: There is no inbound endpoint that matches the beginning of the url you're calling, the easiest solution is to have a catch-all flow with an inbound endpoint whose address is http://localhost:8081/ and log (or not) every message received in that flow.
This MuleSoft tutorial explains how to filter our requests for favicon.ico. You should be able to do the same with requests for robots.txt
New HTTP Listener in 3.6+:
<expression-filter
expression="#[message.inboundProperties.'http.request.uri' != '/robots.txt']" />
For 3.5.0 and less:
<expression-filter
expression="#[payload != '/robots.txt']" />

Timeout error in Until Successful

We have a flow where we have implemented a soap client to send soap messages to Service provider.
We need to retry the service call for 3 times if it fails. So we have used HTTP Outbound Endpoint inside until successful scope.
It is doing retry as expected, but in case of success scenario, even if we get the response from the service, we are observing a time out error as below.
[DispatchThread: 1] org.apache.cxf.endpoint.ClientImpl: Timed out waiting for response to operation {http://support.cxf.module.mule.org/}invoke.
Observation:
I have removed the until successfully and had the HTTP Outbound endpoint directly, in this case there is no timeout error.
I later tried having until successfully and had an acknowledge expression to accept the response, still the same time out response.
failureExpression="#[message.inboundProperties['http.status'] != 200]" ackExpression="#[message.correlationId]"
Could any one please suggest, how to configure the until successful for accepting the response and not throwing time out error.
The ackExpression has nothing to do with "accept the response", it's for generating a value that will be used as the new message payload after the flow has passed the current event to the until-successful message processor.
Try setting a response-timeout on your outbound HTTP endpoint to see if it helps: maybe the default timeout used in the context of the until-successful scope is too big and creates this issue.
I found a solution for this.
Earlier I had only HttpOutbound endpoint inside Until-Successful and I am facing Timeout issue.
Now I included Soap component also inside Until-successful scope it is working fine.
Since until successful allow us to have only one component inside, I have wrapped soap component and HttpOutbound endpoint iside a processor chain.
<until-successful objectStore-ref="objectStore"
maxRetries="3" secondsBetweenRetries="2" deadLetterQueue-ref="xxxx"
doc:name="UntilSuccessfulService" >
<processor-chain doc:name="Processor Chain">
<cxf:jaxws-client operation="Request1" serviceClass="xxxxxxx" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" host="localhost" path="cService" port="xxxx" connector-ref="HTTP_HTTPS"/>
</processor-chain>
</until-successful>
Thanks David and all for your responses.

Apache CXF JMS - SOAP

I need to use the same SOAP request to be able to call the same implementation of a method but which is exposed by 2 different service endpoints:
Endpoint A - would be for synchronous access via SOAP
Endpoint B - would be for asynchronous access via JMS
Now what am seeing is that the SOAP request Message which works on the JMS and the SOAP webservice endpoint are structurally different.
I wanted to know whether with ApacheCXF it is possible to call the SOAP or JMS endpoints using the same SOAP request ?
In my case I was able to call both endpoints but the requests used is not the same for each
Below is an example of the SOAP message which works on Asynch Endpoint B but which does not work on Synch Endpoint A .. note that I've obtained the Asynch message by executing a Junit test and intercepted the generate message on ActiveMQ queue:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:create xmlns:ns1="http://service.ws.example/">
<CustomPartyModel>
<ns2:customerModel
xmlns:ns2="http://party.beans.commons.example">
<ns2:person>
<ns2:budgetPlanNumber>131484</ns2:budgetPlanNumber>
<ns2:clientSituationCode
xmlns:ns3="http://www.w3.org/2001/XMLSchema-instance" ns3:nil="true" />
<ns2:employeeReduction>J</ns2:employeeReduction>
<ns2:employeeNumber></ns2:employeeNumber>
<ns2:packageNumber>5</ns2:packageNumber>
<ns2:planIndicator xmlns:ns3="http://www.w3.org/2001/XMLSchema-instance"
ns3:nil="true" />
<ns2:privateRelationNumber
xmlns:ns3="http://www.w3.org/2001/XMLSchema-instance" ns3:nil="true" />
</ns2:person>
</ns2:customerModel>
</CustomPartyModel>
</ns1:create>
</soap:Body>
Here is the SOAP Request which works on Synchronous endpoint but not on the Asynch one .. this request was obtained from creating a request from the WSDL :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.ws.example/" xmlns:par="http://party.beans.commons.example">
<soapenv:Body>
<ser:CustomPartyModel>
<par:customerModel>
<par:person>
<par:budgetPlanNumber>131484</par:budgetPlanNumber>
<par:employeeReduction>J</par:employeeReduction>
<par:employeeNumber></par:employeeNumber>
<par:packageNumber>5</par:packageNumber>
<par:professionCodePartner></par:professionCodePartner>
<par:professionDescriptionPartner></par:professionDescriptionPartner>
</par:person>
</par:customerModel>
</ser:CustomPartyModel>
In both cases am using Aegis for data binding , I did try JAXB as well but with no futher success.
Given that its the same method with same method signature you would expect that the same request could be used in both asynch and synch but this does not seem to be the case .
Anybody has had similar issues or could possibly shed some light in regards to this ?
Note that am using the following dependencies:
cxf-api-2.2.2.jar ,
cxf-common-utilities-2.2.2.jar,
cxf-rt-databinding-aegis-2.2.2.jar,
XmlSchema-1.4.5.jar,
cxf-rt-transports-jms-2.2.2.jar,
spring-jms-2.5.5.jar,
acegi-security-1.0.7.jar
Ok I found the solution basically to be able to send Request through JMS and Synchronous SOAP as Document Literal the following is required to be defined on the interface
#WebService
#SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL,parameterStyle=ParameterStyle.BARE)
public interface ExampleAsyncService {
Without the Document / Literal / Bare configuration JMS will have a tendancy of sending RPC wrapped style request .