Set specfic host for one flow objects - mule

Im trying to set up my mule project with a specfic host for one of the flow objects.
I have 5 flow objects in my project, all of them calling the same host. But for one of them I need that to point to a different host
MyProject:
flow 1 - 4 =host ${something}
port =443
flow 5 =host some.domain.com
port =443
I can build my project and I can call the endpoint (flow 5) but in the response I can se that it writes out :443 in the host url which casues the call to fail. How can I get rid of the :port in the response url AND is it a better way to set up what Im trying to achive?
Thanks

You can do something like this:
Add lines below on your properties file "mule-app.properties"
api.test1.host=apihostname
api.test1.port=443
api.test1.path=/api
api.test2.host=otherapihost
api.test2.port=443
api.test2.path=/api
Then on your flow global elements, you can add 2 HTTP Request Configuration.
<http:request-config name="API_TEST1_Request_Configuration" host="${api.test1.host}" port="${api.test1.port}" basePath="${api.test1.path}" doc:name="HTTP Request Configuration"/>
<http:request-config name="API_TEST2_Request_Configuration" host="${api.test2.host}" port="${api.test2.port}" basePath="${api.test2.path}" doc:name="HTTP Request Configuration"/>
Then you can use that global reference on your http calls.
Hope this helps.

Related

Https soap service in mule

I have a requirement where soap based service needs to be consumed and in order to achieve that I had used WSConsumer component in Mule.
Where we give the service URL in the properties file and refer to it.
<ws:consumer-config name="Web_Service_Consumer" wsdlLocation="serviceApi.wsdl"
service="serviceAPI" port="serviceApiSoap12Port" serviceAddress="${serviceurl}"
doc:name="Web Service Consumer"/>
Now after the development we came to know that QA web service is a HTTPS web service and while hitting the service following exception is received
SSLHandshakeException: General SSLEngine problem
I'm able to hit the service with Http:request connector as following
<http:request-config name="HTTP_Request_Configuration" host="${host}" port="${port}"
doc:name="HTTP Request Configuration" protocol="HTTPS">
<tls:context>
<tls:trust-store insecure="true" />
</tls:context>
</http:request-config>
But the issue with above config is it won't work for HTTP configuration.
I should be able to connect to both HTTP & HTTPS as I have different environments.
Is there a way where I can achieve this with ws:consumer??
I assume the HTTP connector configuration shown is the one queried by your WS Consumer connector. A simple solution would be to configure the protocol of your HTTP config via property file but Mule doesn't play well with it because you may end-up with a TLS Context configured with HTTP and your connector won't work. There is a little trick you can do however: create 2 HTTP configurations - one for HTTP and one for HTTPS:
<http:listener-config name="HTTPS_Config"
protocol="HTTPS"
host="${host}"
port="${port}"
doc:name="HTTPS Config" >
<tls:context>
<tls:key-store type="${keystore.type}"
path="${keystore.path}"
keyPassword="${keystore.keyPassword}"
password="${keystore.password}"/>
</tls:context>
</http:listener-config>
<http:listener-config name="HTTP_Config"
host="${host}"
port="${port}"
doc:name="HTTP Config" >
</http:listener-config>
In a property file, define which configuration (i.e. which protocol) should be used:
host=localhost
port=443
protocol=HTTPS # or HTTP
And finally in your flow, use your property to reference the proper HTTP(S) config:
<flow name="http-testFlow">
<http:listener config-ref="${protocol}_Config" path="/test" doc:name="HTTP"/>
...
</flow>
The trick is to name your configuration ${protocol}_Config such as HTTP_Config and HTTPS_Config so the proper one is used at runtime via config-ref="${protocol}_Config". Mule will then dynamically use the proper configuration when your app is launched. This is entirely transparent for the user as only the protocol (HTTP vs. HTTPS) needs to be configured, and it can be used in any environment.
You can use this differently, the idea is to have Mule pick your HTTP or HTTPS dynamically at runtime.
EDIT: to configure your WS Consumer with HTTPS you'll need to reference a proper HTTP Requester Configuration such as:
<ws:consumer-config name="Web_Service_Consumer"
...
connectorConfig="HTTP_Request_Configuration"/>
<http:request-config name="HTTP_Request_Configuration"
...
<tls:context>
...
</tls:context>
...
/>
See Web Service Consumer documentation for details.
Note: though this solution works I would recommend using HTTPS all the time, for security reasons and to have less differences between your dev/QA/Prod/... environments - among other things.
I faced similar issues, we finally chose to have only an HTTPS config and define via property which keystore to use at runtime. In dev we would use a self-signed certificate and a proper keystore in environments requiring proper security.
Hope this helps.

Mule HTTP transport deprecated

I use the new HTTP Connector as mentioned in the online documentation:
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081"/>
<flow name="test_flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="NEW HTTP Connector"/>
<...>
</flow>
Yet, when deploying in DEV on Cloudhub, I still get the message:
HTTP transport is deprecated and will be removed in Mule 4.0. Use HTTP
module instead.
I'm not sure what to look for. Is this a known issue?
While deploying to mule cloudhub, please change the host in listener config from local host to the default All interfaces [0.0.0.0].
Change your HTTP Connector to use "0.0.0.0" instead of your CloudHub domain name and redeploy.

Dynamically switch http:listener-config configuration in mule

I would like to have the ability to switch listener configuration easily in Mule (CE-3.6.1) from http to https (with basic autentication). I've created a variable in the mule-project.xml 'mule.protocol' and two properties files http.properties and https.properties with some data like port (the same port in http and https), host, password, etc.
in config.xml I have:
<context:property-placeholder location="${mule.protocol}.properties" />
<http:listener-config name="HTTP_Listener_Configuration" host="${host}" port="${port}" doc:name="HTTP Listener Configuration" protocol="${protocol}">
<tls:context>
<tls:key-store type="${keystore.type}" path="${keystore.path}" keyPassword="${keystore.keyPassword}" password="${keystore.password}" />
</tls:context>
</http:listener-config>
but I have two problems.
First, I get a message: Value '${protocol}' is not man-valid with respect to enumeration '[HTTP, HTTPS]'
and the second, section 'tls:context' is permitted only in https case, so I would have to hide it dynamically. How to solve these problems or whether there is another way to easily switch between the configuration of http and https? I'm using HTTP_Listener_Configuration in many services.
Unfortunately, this was only added for Mule 3.8.0 (coming soon). In older versions the protocol attribute does not support properties. You could use a Spring profile as a workaround. You can find more data in the JIRA ticket for this.

Mule-ESB HTTP redirect does not work when followRedirects=false

I have a simple flow that didn’t work for mule. In my setup, I am listening on one port for HTTP traffic and forwarding traffic on another port which I believe is the most typical ESB use case. The proxy/gateway flow works except when the target application issues redirect. Does anyone know of any tricks to address this? Note that I can not use the "HTTP-Proxy pattern" from mule as I intend to extend this flow for more complex use case.
Mule Flow
<http:listener-config name=“HTTP_IN" host=“localhost" port="12344" doc:name=“IN_EP" />
<http:request-config name=“HTTP_OUT" host=“localhost" port="8380" doc:name=“OUT_EP"/>
<flow name="test2Flow2">
<http:listener config-ref=“HTTP_IN" path="*" doc:name="IN"/>
<logger level="INFO" doc:name="Request Logger"/>
<http:request config-ref=“HTTP_OUT" path="#[message.inboundProperties.'http.request.path']" method="#[message.inboundProperties.'http.method']" doc:name="OUT" followRedirects="false" />
<response>
<logger level="INFO" doc:name="Response Logger"/>
</response>
</flow>
Case 1: followRedirects=true (default)
In this case mule gets HTTP 302 from target end point and it internally navigates to the redirected page and serves the page to the client. This is great if I am using Mule as a gateway to some web services. However for HTTP traffic from browser, if we allow this to happen, all the relative URLs will break from the rendered page.
Case 2: followRedirects=false
In this case mule gets HTTP 302 from target end point and it drops the response after logging it. Mule just send HTTP 200 on the browser with empty HTML page. See logs below for case 2. I like to send the HTTP 302 response to the end-user.
Request Logged (Case 2)
INFO 2015-10-01 13:01:48,333 [[test2].APP_A_IN.worker.01] org.mule.api.processor.LoggerMessageProcessor:
org.mule.DefaultMuleMessage
{
Message properties:
INVOCATION scoped properties:
INBOUND scoped properties:
accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-encoding=gzip, deflate, sdch
accept-language=en-US,en;q=0.8
cache-control=max-age=0
connection=keep-alive
dnt=1
host=localhost:12344
http.listener.path=/*
http.method=GET
http.query.params=ParameterMap{[]}
http.query.string=
http.relative.path=/app_a
http.remote.address=/127.0.0.1:53372
http.request.path=/app_a
http.request.uri=/app_a
http.scheme=http
http.uri.params=ParameterMap{[]}
http.version=HTTP/1.1
upgrade-insecure-requests=1
user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
x-firephp-version=0.0.6
OUTBOUND scoped properties:
SESSION scoped properties:
}
Response Logged (Case 2)
INFO 2015-10-01 13:01:48,420 [[test2].APP_A_IN.worker.01] org.mule.api.processor.LoggerMessageProcessor:
org.mule.DefaultMuleMessage
{
Message properties:
INVOCATION scoped properties:
INBOUND scoped properties:
date=Thu, 01 Oct 2015 17:01:48 GMT
http.reason=Moved Temporarily
http.status=302
location=http://localhost:8380/app_a/
server=Apache-Coyote/1.1
transfer-encoding=chunked
OUTBOUND scoped properties:
SESSION scoped properties:
}
I think the problem is that you are not copying the properties from the requester to the listener's response. I suggest using a copy-properties element right after the requester. The inbound properties will be lost otherwise: you need them as outbound at that point.
Some properties like the http.status might need to be mapped to headers explicitly using a response-builder though.
HTH

hostName in webservice endpoint in mule config?

I have a mule application which needs to be deployed in different servers. I have question for setting the hostname for HTTP based endpoint address
Should host name come from properties file, replacing it at build time based on the environment for which the application is being built --
Example --
http:inbound-endpoint address="http://${host.name}:61005/my/service" exchange-pattern="request-response"
Or is it possible to build the deployable app with hostname as localhost and replace it at deployment time
Example --
http:inbound-endpoint address="http://localhost:61005/my/service" exchange-pattern="request-response"
Thanks in advance.
You could use 0.0.0.0 as the host and it will listen on every network interface of the server:
<http:inbound-endpoint address="http://0.0.0.0:61005/my/service" exchange-pattern="request-response" />
It means that if, for example, your server has the IP 192.168.0.1, it will automatically server requests at http://192.168.0.1:61005/my/service/
It will save you from configuring a deployment file.
A properties file would work fine but keep in mind Spring's Property Placeholder Resolver can also get values from Java system properties so you could provide a value for ${host.name} at start-up with:
mule -M-Dhost.name=$HOSTNAME