Mule HTTPS POST request not working when deployed to Cloudhub - api

I have a Mule application that is calling an external API over HTTPS using the <http:request connector. When I build and deploy my application locally, the call works fine. When I make a Postman call to the same external API using the exact same payload my Mule app sends, the call works fine. However, when I deploy the Mule app to Cloudhub and make the request - I get a 400 response from the external API.
Here's my flow:
<http:request-config name="mambuRequestConfiguration" protocol="HTTPS" doc:name="HTTP Request Configuration">
<http:basic-authentication username="${mambu.username}" password="${mambu.password}" preemptive="true" />
<tls:context>
<tls:key-store type="jks" path="keystore.jks" alias="${keystore.alias}" keyPassword="${keystore.keypassword}" password="${keystore.password}" />
</tls:context>
</http:request-config>
<flow name="createClientDepositAccount">
<dw:transform-message metadata:id="412fd434-12bb-47a3-9605-9bfc1d9fec46" doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
savingsAccount: {
accountHolderKey: payload.clientKey,
accountHolderType: "CLIENT",
productTypeKey: payload.productKey,
name: payload.clientProductName,
accountType: payload.accountType,
accountState: payload.accountState,
interestRate: payload.interestRate
}
}]]></dw:set-payload>
</dw:transform-message>
<http:request config-ref="mambuRequestConfiguration" path="${mambu.deposit.path}" method="POST" host="${mambu.host}" port="${mambu.port}" doc:name="Mambu: Create Client Deposit Account">
<http:success-status-code-validator values="0..599"/>
</http:request>
<dw:transform-message metadata:id="49f1231f-485f-433c-82c4-3d83856ac442" doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
message: "Account created successfully",
key: payload.savingsAccount.encodedKey
}]]></dw:set-payload>
</dw:transform-message>
</flow>
The external service I'm calling is Mambu, a cloud banking platform. I have a number of other flows in my application all making GET requests to various other Mambu APIs - all work fine (all GET requests are also over HTTPS). The response I'm getting from Mambu is a 400 with the payload:
{"returnCode":3,"returnStatus":"INVALID_API_OPERATION"}
Relevant links to the Mambu documentation are here and here.
I'm unable to replicate the behaviour I'm seeing in Cloudhub on my local instance. The only thing that differs about this call to the others I'm making is that it's a POST request.

In most cases this error is related to the API auto-discovery being improperly configured or corrupt. If API auto-discovery is configured on the Mule application, the best solution is to remove the setting from the Mule application, check if the error is resolved by starting the process again, then reconfigure the auto-discovery.

Bizarrely, the resolution to this was "turn it off and on again" as suggested on a question I posted on the Mulesoft forum. I simply deleted the app from Cloudhub and redeployed it and everything worked as expected. Very strange issue within Cloudhub by the looks of things. Hopefully Mulesoft will resolve...

Related

Implementing Server Sent Events with Mule 4.4.0

I am trying to implement Server Sent Events using the HTTP connector in Mule 4.4.0. I have a flow with an http listener that is accepting SSE client connections and responding to the SSE heartbeat
<flow name="SSE_Subscribe_Flow">
<http:listener doc:name="Listener" config-ref="HTTP_Listener_config" path="/events/subscribe" allowedMethods="GET" responseStreamingMode="ALWAYS">
<http:response statusCode="200" >
<http:headers><![CDATA[#[output application/java
---
{
"Content-Type" : "text/event-stream",
"Cache-Control" : "no-cache",
"Connection" : "keep-alive"
}]]]>
</http:headers>
</http:response>
</http:listener>
<logger level="INFO" message="#[message]"/>
</flow>
Is it possible to push messages to the open connection from other flows?
Mule currently doesn't support Server-Sent Events. As an alternative, if you can use Websockets instead note that Mule 4 has a Websockets connector.

Mule http request giving 404 mapped as failure

I am trying to pass the multiple URI params in the http request as follows:
<http:listener-config name="HTTP_Listener_Configuration"
host="localhost" port="8081" doc:name="HTTP Listener Configuration"
connectionIdleTimeout="40000" />
<http:request-config name="HTTP_Request_Configuration1" protocol="HTTPS" host="" port="443" doc:name="HTTP Request Configuration" connectionIdleTimeout="300000" responseTimeout="50000">
<http:basic-authentication username="user" password="123"/>
</http:request-config>
<flow name="testFlow">
<http:listener config-ref="HTTP_Listener_Configuration"
path="/paypal" allowedMethods="GET" doc:name="HTTP" />
<set-variable variableName="config" value="#[{'p1':'3054', 'p2':'child/Lines'}]" doc:name="Variable"/>
<http:request config-ref="HTTP_Request_Configuration1" path="/resources/shipment/{p1}/{p2}" method="GET" doc:name="HTTP">
<http:request-builder>
<http:uri-params expression="#[flowVars.config]"/>
</http:request-builder>
</http:request>
</flow>
But this is giving me error as below:
Response code 404 mapped as failure.
ERROR 2019-01-04 18:46:34,526
[[paypaltest].HTTP_Listener_Configuration.worker.01]
org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Response code 404 mapped as failure.
Payload : org.glassfish.grizzly.utils.BufferInputStream#b473ec2
Element : /testFlow/processors/1 # test:test.xml:29 (HTTP)
Element XML : <http:request config-ref="HTTP_Request_Configuration1" path="/resources/shipments/{p1}/{p2}" method="GET" doc:name="HTTP">
<http:request-builder>
<http:uri-params expression="#[flowVars.config]"></http:uri-params>
</http:request-builder>
</http:request>
--------------------------------------------------------------------------------
Root Exception stack trace:
org.mule.module.http.internal.request.ResponseValidatorException: Response code 404 mapped as failure.
Please let me know if any help can be provide!
It means that the url doesn't exist. Try to hit the url directly in postman before implementing in Mule. Since you wiped out the host="", I'll pretend it's example.com. My guess is that it's having an issue with p2. If you'd like to send the actual string, you'll need to URL encode the "/", which is %2F
So to test hit https://www.example.com/resources/shipments/3054/child%2FLines, with the Basic Auth for Authorization.
Postman: https://www.getpostman.com/apps
The issue i faced was unique to me, i tried this REST api call from SOAPUI and there it gave me the same error i.e. 404 not found so i compared it with POSTMAN request and found that Authorization header was the missing piece for this.
After adding this to http header it worked perfectly.
Please refer
https://docs.mulesoft.com/connectors/http/http-authentication
here are two solutions :
1. Add preemptive="true" in basic authentication configuration
The pre-emptive option passes the user name and password without waiting for a prompt from the server.
Add Authorization in the http:header value ="Basic dXNlcjoxMjM="

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 method cannot be cast to string

i'm very new to mule studio.
This is the environements setup.
VM1 = Windows 7, Visual Studio 2012, IIS 7.
A .net 4.5 WCF webservice hosted in IIS7 that has an operation that accepts a string and returns a string.
VM2 = Ubuntu 13.4 OpenJDK 1.7.0_25 Mule Studio 3.5 Community Edition.
I created a JAXWS-Client with an outbound endpoint, I did this by clicking the generate from WSDL and entering the url of the .net WCF webservice hosted in IIS on VM1. That was fine.
I then created an inbound endpoint with a jaxws-Service in-between the inbound service and the outbound client there is a logger and an object to string.
If I setup a vanilla inbound endpoint (no soap) and use a simple html form to post it all works fine and I get a string back to the browser. But adding the Soap Component causes the dispatcherexception when the flow hits the Soap Component just prior to the outbound endpoint.
org.mule.api.transport.DispatchException: java.lang.reflect.Method
cannot be cast to java.lang.String. Failed to route event via
endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor. Message
payload is of type: String
<flow name="testtwoFlow1" doc:name="testtwoFlow1">
<http:inbound-endpoint exchange-pattern="request-response" path="SimplePing" doc:name="HTTP" host="0.0.0.0" port="8081"/>
<cxf:jaxws-service serviceClass="TestTwo.IPing" doc:name="SOAP" />
<logger level="INFO" doc:name="Logger"/>
<object-to-string-transformer doc:name="Object to String"/>
<flow-ref name="testtwoFlow3" doc:name="Flow Reference"/>
</flow>
<sub-flow name="testtwoFlow3" doc:name="testtwoFlow3">
<cxf:jaxws-client operation="SimplePing" serviceClass="TestTwo.IPing" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<logger level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="192.168.0.2" port="80" path="MuleExperiments/Ping.svc" method="POST" doc:name="HTTP" />
</sub-flow>
I Have googled extensively and I haven been much in the way if examples that show an inbound service interacting with an outbound client. Or descriptions of the exception thrown, what causes it and how to address it. I'm guessing pretty much its because the service and the client are generated from the same WSDL, but I wouldn't have thought that would be a real issue. Or that in my cxf:jaxws-service & cxf:jaxws-service the service class is the same.
What my goal is, at this juncture, is to have a simple in/out of a string
My client was wrongly configured. It should have been clientClass, not serviceClass, and the port needed to be set as well. Once I made these changes, I got it working.
<cxf:jaxws-client
operation="SimplePing"
enableMuleSoapHeaders="true"
doc:name="SOAP"
clientClass="TestTwo.PingService"
port="BasicHttpBinding_IPing"
/>

Timed Mule Web Service Client Flow

I've searched the forums for an answer to this. I found one almost identical question, though the answer left me still wondering.
An almost identical post was found here:
Mule - Schedule a flow to consume a web service
This poster stated the problem I am having very well.
I am also new to Mule and am trying to do the very same thing. I didnt realize I needed a payload since I thought the operation specification was essentially the payload.
Notice that I have a flow that includes cxf:jaxws-client and that client specifies a URL for the service and an operation "listTest".
What other payload do i need to specify in order to actually execute the service request?
I tried to add a dummy payload to the event generator (as suggested in referenced post), and that doesnt make a difference.
When I execute the mule application, and monitor the "test auditor web service" (using wireshark) i see four requests go out for the wsdl, and i see that wsdl returned, but i dont actually see the listTest operation getting invoked.
My flow is:
<http:connector name="HTTP_HTTPS" cookieSpec="netscape"
validateConnections="true" sendBufferSize="0" receiveBufferSize="0"
receiveBacklog="0" clientSoTimeout="10000" serverSoTimeout="10000"
socketSoLinger="0" doc:name="HTTP\HTTPS" />
<flow name="TestAuditorClient_CheckerFlow1" doc:name="TestAuditorClient_CheckerFlow1">
<quartz:outbound-endpoint jobName="GetTestList"
repeatInterval="10000" responseTimeout="10000" doc:name="Quartz">
<quartz:event-generator-job jobGroupName="GetTestList" />
</quartz:outbound-endpoint>
<cxf:jaxws-client operation="listTest"
clientClass="server.TestService_Service" port="TestServicePort"
wsdlLocation="http://192.168.66.7:8080/TestAuditorWebApp/TestService?wsdl"
doc:name="SOAPY" />
<outbound-endpoint
address="http://192.168.66.7:8080/TestAuditorWebApp/TestService"
doc:name="HTTP" />
<logger message="Received HTTP Response #[payload]" level="INFO"
doc:name="Logger" />
<!-- <outbound-endpoint exchange-pattern="request-response" address="http://192.168.66.17:8080/TestAuditorWebApp/TestService"
doc:name="HTTP"/> -->
<file:outbound-endpoint path="C:\tmp"
outputPattern="#[function:datestamp:dd-MM-yy]_#[function:systime].txt"
responseTimeout="10000" doc:name="Output File" />
</flow>
I am not only new to mule, but as well to stack overflow. So if there was a better way for me to ask a related question, please advise and excuse.
Thanks in advance.
Instead of Quartz, you can use a poll message processor to generate the instances of ListTest you need.
Assuming this class FQDN is server.TestService.ListTest (you didn't tell), the following should work:
<flow name="TestAuditorClient_CheckerFlow1">
<poll frequency="10000">
<set-payload value="#[lt=new server.TestService.ListTest(); lt.aField='aValue'; lt]" />
</poll>
...
Notice how you can set values on the POJO directly from the expression that creates it.