Mule 4 : What is the advantage of Remove variable Transformer? - mule4

Why should we use the remove variable transformer in mule 4?
Because each flow have their own fresh copy of variables when they are called, which means the variables are destroyed by mule itself after the flow completes execution.
To test this theory, I create a Mule flow :
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="955e025a-379f-49f5-8623-b79b70dedf94" >
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<flow name="remove-variable-exampleFlow" doc:id="7f545df1-b0cf-4b86-bbcc-cba1f9d0a322" >
<http:listener doc:name="Listener" doc:id="7d4a9fa8-9760-478a-b75b-0f205ec81ba6" config-ref="HTTP_Listener_config" path="/create"/>
<logger level="INFO" doc:name="Log request arrived" doc:id="6e1d8be9-ac47-4f51-8c17-fd114fe583d5" message='#["Request arrived, Value of temp before initilaization : " ++ (vars.temp default "")]'/>
<set-variable value='#["Random value : " ++ (random()*1000)]' doc:name="Set Temp" doc:id="20de7738-a476-46e6-a442-3a5435092d68" variableName="temp"/>
<logger level="INFO" doc:name="Logger" doc:id="058eaa05-90c9-49c0-b853-9286a01191a0" message='#["Request arrived, Value of temp after initilaization : " ++ vars.temp]'/>
</flow>
</mule>
And the result of every time I made the call is :
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp before initilaization :
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp after initilaization : Random value : 588.1040740493614
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp before initilaization :
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp after initilaization : Random value : 582.2399134793665
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp before initilaization :
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp after initilaization : Random value : 743.1259073180681
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp before initilaization :
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Request arrived, Value of temp after initilaization : Random value : 526.9686552199496
So what is the advantage of using Remove variable transformer in Mule 4?

Advantages make sense in comparing scenarios. In your particular example, there is none, because the flow is too simple and just doesn't need it, and you are not comparing to anything else. However in more complex applications you may have the need to remove a variable before some other operation. For example if you reuse the same variable or if the presence of the variable is used as a flag for a condition.
As you said, it is not used to clear variables when the execution of the flow (event) finishes. That is not needed.

Related

Mule ESB conditional Exchange pattern for UDP/TCP transport

I need to send an acknowledge response for some messages went an acknowledge needed flag is set for that purpose.
Using a Java component I build a Payload string array with this structure:
Payload[0]=message entry.
Payload[1]="true"/"false" // This is the acknowledge needed flag.
Payload[2]="OK"/"ON"/"OFF"// Response to the transport (went flag="true")
This is my XML code
<tcp:connector name="TCP" validateConnections="false" sendBufferSize="0" receiveBufferSize="0" receiveBacklog="0" keepAlive="true" clientSoTimeout="10000" serverSoTimeout="10000" socketSoLinger="0" doc:name="TCP">
<tcp:direct-protocol rethrowExceptionOnRead="true" payloadOnly="true"/>
</tcp:connector>
<flow name="verifyFlow">
<tcp:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9446" connector-ref="TCP" responseTimeout="10000" doc:name="TCP" transformer-refs="Byte_Array_to_String"/>
<component class="verify.as" doc:name="Java Component"/>
<choice doc:name="Choice">
<when expression="#[message.payload[1] == 'false']">
<set-payload value="""" doc:name="No response"/>
</when>
<otherwise>
<expression-transformer mimeType="text/plain" expression="#[message.payload[2]]" doc:name="Expression"/>
</otherwise>
</choice>
</flow>
The problem I'm facing is that went ever the flag is "false" there shouldn't be any response send to the transport (no 'null' value, no empty string, no "", Etc.) ¿Is there any way to change the exchange pattern of the TCP (or UDP) connector from request-response to one way inside the flow?

How to get the incoming cookies to a Mule HTTP end point

I'm using Mule EE 3.5.2.
I'm posting an HTTP request (PostMan) with a cookie header, to an incoming HTTP end point in Mule. How can I read this Cookie?
In practice this cookie will be coming through an NGinX proxy; i need it to pass to another application.
First make sure your connector have enableCookies="true".
Then you'll find a inboundProperty called cookies of type Lorg.apache.commons.httpclient.Cookie.
To access them just #[message.inboundProperties['cookies'].
Here's how to save the cookies from a rest response in a session variable without a custom java class.
<set-session-variable variableName="incomingCookies" value="#[org.mule.transport.http.CookieHelper.parseCookiesAsAClient(message.inboundProperties['set-cookie'],null)]" doc:name="Set incomingCookies as Session Variable"/>
<set-variable variableName="cookie-name" value="#[org.mule.transport.http.CookieHelper.getCookieValueFromCookies(incomingCookieMap,'cookie-name')]" doc:name=“Set cookie-name as Flow Variable”/>
You can use a similar approach for extracting cookies from a rest request using the parseCookiesAsAServer method from the CookieHelper class.
More info on the CookieHelper class is here https://www.mulesoft.org/docs/site/3.8.0/apidocs/org/mule/transport/http/CookieHelper.html
That doesn't work anymore with the new http:listener component.
Setting that property will give :
org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'enableCookies' is not allowed to appear in element 'http:listener'.
So how to do this with the new http:listener component...
A problem I had was that I needed to access the cookies that came in and Mule only provides the cookies in an unformatted string.
So this is an option a friend of mine developed, which I enhanced a bit to get easy access to the cookies in a flow:
package transformers;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.PropertyScope;
import org.mule.transformer.AbstractMessageTransformer;
import org.mule.transport.http.CookieHelper;
import org.apache.commons.httpclient.Cookie;
public class CookieGrabber extends AbstractMessageTransformer {
public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
Object _CookieHeader = message.getInboundProperty("Cookie");
List<Cookie> _CookieList = null;
Map<String,String> _CookieMap = new HashMap<String,String>();
try {
//Grab the cookies from the header and put them into a List
_CookieList = (List<Cookie>) Arrays.asList(CookieHelper.parseCookiesAsAServer(_CookieHeader.toString(),
new URI("" + message.getInboundProperty("host"))));
//And put them in a convenient List which can be accessed from the flow
message.setProperty("incomingCookieList", _CookieList, PropertyScope.SESSION);
//Let's also put them in a nice Map, since incoming cookies will
//usually only contain a name and a value, so let's get easy access to them by their name.
for (Cookie _Cookie : _CookieList){
_CookieMap.put(_Cookie.getName(), _Cookie.getValue());
}
message.setProperty("incomingCookieMap", _CookieMap, PropertyScope.SESSION);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return message;
}
}
Then there is this flow example which shows how to use this code snippet.
It contains a listener that sets some cookies, forwards it to a "proxy", which will read the cookies, but also forward the request to another endpoint, making it a transparent proxy, but which does read the cookies in the process.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
version="EE-3.6.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
<custom-transformer class="transformers.CookieGrabber"
name="MyCookieTranformer"
doc:name="Java"/>
<http:listener-config name="HTTP_Configuration_CookieHandlerExample"
host="0.0.0.0"
port="8080"
doc:name="HTTP Listener Configuration"/>
<http:request-config name="HTTP_Request_Configuration"
host="localhost"
port="8080"
doc:name="HTTP Request Configuration"/>
<flow name="CookieSetterFlow">
<http:listener config-ref="HTTP_Configuration_CookieHandlerExample"
path="/setCookies/*"
doc:name="setCookies"
doc:description="Call this module by entering http://localhost:8080/setCookie"/>
<message-properties-transformer doc:name="Set the cookies"
doc:description="Set some random cookies in the header">
<add-message-property key="Cookie"
value="token=abcde; name=dennis"/>
</message-properties-transformer>
<http:request config-ref="HTTP_Request_Configuration"
path="/proxyCookie"
method="GET"
doc:name="call proxyCookies"
doc:description="Invoke the cookieReceiver with the cookies we've just set. Note the failure status code validator with a non-existing http code. It's a nasty bug, but it works like this...">
<http:failure-status-code-validator values="00000"/>
</http:request>
</flow>
<flow name="CookieProxyFlow">
<http:listener config-ref="HTTP_Configuration_CookieHandlerExample"
path="/proxyCookie"
doc:name="proxyCookies"
doc:description="This connector will proxy the cookieReceiver"/>
<transformer ref="MyCookieTranformer"
doc:name="GrabCookies"
doc:description="Use our custom transformers.CookieGrabber class to put the cookies in a nice java.util.List in a session variable."/>
<logger message="CookieProxy: Value of cookie "token": "#[sessionVars.incomingCookieMap.get('token')]"."
level="INFO"
doc:name="Have a cookie!"
doc:description="Let get a cookie value, simply by referring the name of it as the key from our map"/>
<flow-ref name="copy-and-clean-headers"
doc:name="copy-and-clean-headers"
doc:description="Cope the headers and clean the Mule stuff from the headers to forward it clean to the receiver."/>
<set-property propertyName="host"
value="localhost"
doc:name="Set Host"
doc:description="Now not really necessary, but you'll probably want to set the hostname to the actual service endpoint."/>
<http:request config-ref="HTTP_Request_Configuration"
path="/receiveCookie"
method="GET"
doc:name="forward to receiveCookies"
doc:description="Invoke the cookieReceiver.">
<http:failure-status-code-validator values="00000"/>
</http:request>
<flow-ref name="copy-and-clean-headers"
doc:name="copy-and-clean-headers"
doc:description="Again copy the headers and clean the Mule http stuff."/>
</flow>
<sub-flow name="copy-and-clean-headers" >
<copy-properties propertyName="*"
doc:name="Copy All HTTP Headers"/>
<remove-property propertyName="Content-Length"
doc:name="Remove Content Length"/>
<remove-property propertyName="MULE_*"
doc:name="Remove MULE Properties"/>
<remove-property propertyName="X_MULE*"
doc:name="Remove X_MULE Properties"/>
<remove-property propertyName="http.*"
doc:name="Remove http Properties"/>
</sub-flow>
<flow name="CookieReceiverFlow">
<http:listener config-ref="HTTP_Configuration_CookieHandlerExample"
path="/receiveCookie"
doc:name="receiveCookies"
doc:description="This connector receives the cookies we've just set"/>
<transformer ref="MyCookieTranformer"
doc:name="GrabCookies"
doc:description="Use our custom transformers.CookieGrabber class to put the cookies in a nice java.util.List in a session variable."/>
<logger message="CookieReceiver: Value of cookie "token": "#[sessionVars.incomingCookieMap.get('token')]". Yep, still there :)"
level="INFO"
doc:name="Have a cookie!"
doc:description="Let get a cookie value, simply by referring the name of it as the key from our map"/>
<set-payload value="#[sessionVars.incomingCookieList.toArray(String)]"
doc:name="Put CookieList to payload"
doc:description="Put the session vairable List that contains the cookies in the payload"/>
<json:object-to-json-transformer returnClass="java.lang.String"
doc:name="Object to JSON"
doc:description="Convert our payload to a JSON object"/>
</flow>
</mule>
You can test it by running it and opening this page: http://localhost:8080/setCookies
Hope this helps.
You can fetch the cookies with:
#[headers:INBOUND:cookie] or #[message.inboundProperties['cookie']]

How to implement HTTP Basic Authentication with synchronous JMS in Mule ESB?

I've created a simple flow that exposes an HTTP endpoint linked to a REST service. The REST service returns a String which is then placed onto a JMS queue using the request-response pattern. The idea is that the String placed on the queue will be consumed by some consumer and a reponse will created using the Reply-To address. So basically this is implimenting synchronous JMS.
The flow works as expected, except when the HTTP endpoint is secured using Basic Authentication. In this case the response is:
java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1
and no message is placed on the queue. Removing Basic Authentication results in no exception being thrown. Also, removing the JMS outbound endpoint results in the String being echoed back which leads me to believe the problem is with the JMS endpoint. I suspect that the problem is with the response from the JMS endpoint because setting component in the flow to one-way negates the problem. I think the issue might be that the endpoint is sending some response to the HTTP endpoint without authentication credentials and it fails because of it, but I'm unsure how to deal with this.
Below is the flow that I created:
<mule
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:core="http://www.mulesoft.org/schema/mule/core"
version="CE-3.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:ss="http://www.springframework.org/schema/security" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/3.1/mule-spring-security.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd ">
<jms:activemq-connector name="Active_MQ" specification="1.1" brokerURL="tcp://localhost:61616"
validateConnections="true" doc:name="Active MQ"/>
<mule-ss:security-manager>
<mule-ss:delegate-security-provider name="memory-provider" delegate-ref="authenticationManager"/>
</mule-ss:security-manager>
<spring:beans>
<ss:authentication-manager alias="authenticationManager">
<ss:authentication-provider>
<ss:user-service id="userService">
<ss:user name="username" password="password" authorities="ROLE_ADMIN"/>
</ss:user-service>
</ss:authentication-provider>
</ss:authentication-manager>
</spring:beans>
<flow name="RESTAPISync" doc:name="RESTAPISync">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP">
<mule-ss:http-security-filter realm="realm"/>
</http:inbound-endpoint>
<jersey:resources doc:name="REST">
<component class="SFREST"/>
</jersey:resources>
<jms:outbound-endpoint exchange-pattern="request-response" queue="tmp" connector-ref="Active_MQ"
doc:name="JMS"/>
</flow>
The SFREST.java component:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("/pops")
public class SFREST{
#GET
public String getPOPs() throws Exception{
return "hello";
}
}
And the exception:
ERROR 2012-11-04 21:40:57,485 [[jmstest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Authentication Attempt Failed. Message payload is of type: String
Code : MULE_ERROR-54999
--------------------------------------------------------------------------------
Exception stack is:
1. Bad credentials (org.springframework.security.authentication.BadCredentialsException)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider:137 (null)
2. Authentication Attempt Failed. Message payload is of type: String (org.mule.api.security.UnauthorisedException)
org.mule.security.MuleSecurityManager:96 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/security/UnauthorisedException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.springframework.security.authentication.BadCredentialsException: Bad credentials
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:137)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.mule.module.spring.security.SpringProviderAdapter.authenticate(SpringProviderAdapter.java:70)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
ERROR 2012-11-04 21:41:04,522 [[jmstest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1
Code : MULE_ERROR-29999
--------------------------------------------------------------------------------
Exception stack is:
1. com.sun.jersey.spi.container.ContainerResponse (java.io.NotSerializableException)
java.io.ObjectOutputStream:1164 (null)
2. java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException)
org.apache.commons.lang.SerializationUtils:111 (null)
3. java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1 (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:35 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.commons.collections.map.AbstractHashedMap.doWriteObject(AbstractHashedMap.java:1182)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Any ideas?
Turns out the problem was that the jersey_response property can't be serialized and needs to be removed. So regardless of what the payload is as long as this property is in the message, the message can't be passed to the JMS outbound component. More info can be found at:
http://forum.mulesoft.org/mulesoft/topics/http_authentication_with_jms_request_response?utm_content=topic_link&utm_medium=email&utm_source=reply_notification
The reason of the exception is because any jersey component returns a com.sun.jersey.spi.container.ContainerResponse that you need to transform before propagating it to the next message processor as explained here

Mule 3 : async reply w/ reply on different main flow thread

I'm new to Mule, and am working on a problem that requires a flow that diapatches messages to a Mule message bus that listeners can receive to also receive notification of successful processing of those messages when the workers are done. The main criteria is that the 'dispatcher flow' not be blocked from continuing to do its work (of placing other different messages on the bus for potentially other listeners).
I have a test app that I've been running in MuleStudio (below) that encapsultates the basics of what I'm trying to achieve, simplified; this is a very simple 2 flow app, using request-reply to allow the 2nd flow to send a reply back to the main flow; the main issue here is that the main flow's thread is blocked, preventing it from doing anything until the response comes back. Is there a way to have the response come back on a different thread of the main flow, or are there other ways of accomplishing this given the criteria ?
Thanks for any help or pointers ;-)
...
<!-- simple Groovy transformer that changes the msg payload to a greeting w/ the current time-->
<scripting:transformer name="toCurrentTime">
<scripting:script engine="groovy">
import java.text.SimpleDateFormat;
def DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
def cal = Calendar.getInstance();
def sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
return "Response # time " + sdf.format(cal.getTime())
</scripting:script>
</scripting:transformer>
<!--
note : neither of the following are allowed on the flow b/c of the request-reply
processingStrategy="synchronous"
processingStrategy="queued-asynchronous"
-->
<flow name="main" doc:name="main">
<http:inbound-endpoint ref="httpEventInjector" doc:name="HTTP"/>
<logger message="starting main flow" level="INFO"/>
<request-reply storePrefix="mainFlow">
<vm:outbound-endpoint path="worker"></vm:outbound-endpoint>
<vm:inbound-endpoint path="reply"></vm:inbound-endpoint>
</request-reply>
<!-- processing continues once we get the response on the 'reply' channel above from the worker -->
<!-- generate the response for the browser -->
<logger message="finishing main flow w/ browser response" level="INFO"/>
<response>
<transformer ref="toCurrentTime"/>
</response>
</flow>
<flow name="worker" doc:name="worker">
<vm:inbound-endpoint path="worker"/>
<logger message="starting worker task(s) ...." level="INFO"/>
<scripting:component doc:name="thread-sleep(10s)">
<scripting:script engine="Groovy">
System.out.println "about to sleep # time" + System.currentTimeMillis()
Thread.sleep(10000);
System.out.println "done sleeping # time" + System.currentTimeMillis()
</scripting:script>
</scripting:component>
<logger message="finishing up worker task(s) ...." level="INFO"/>
</flow>
You can use continuations to achieve what you want. I've written a blog post about this topic.

How to Edit Default Mule Error message..?

I have defined a Mule HTTP Inbound Endpoint as :
<flow name="jfeed_fill_data">
<http:inbound-endpoint address="http://localhost:1212/jcore/insert/feed/">
</http:inbound-endpoint>
<component class="main.java.com.joshlabs.jcore.Feed"/>
</flow>
Now this Service Works Fine.
But When i type a Deformed URL , something like "http://localhost:1212/jcore/insert/feedasdasdAwes/", I get the following Message from MULE :
Cannot bind to address "http://localhost:1212/jcore/insert/feedasdasdAwes/"
No component registered on that endpoint
My Question is : How can i Change the above default Message to Something of my own.?
Note : Actually i wanted to return a JSON String as an Error message. Something like :
{
Exception: "Invalid URL"
}
And if possible, then "Can MULE throw HTTP 404 : Not Found Error in above case"..??
You just need to make your endpoint accept all sub-paths and then handle wrong ones with message routing:
<flow name="jfeed_fill_data">
<http:inbound-endpoint address="http://localhost:1212" />
<choice>
<when evaluator="header" expression="INBOUND:http.request.path=/jcore/insert/feed/">
<component class="main.java.com.joshlabs.jcore.Feed"/>
</when>
<otherwise>
<message-properties-transformer>
<add-message-property key="http.status" value="404"/>
</message-properties-transformer>
<expression-transformer>
<return-argument evaluator="string" expression="{Exception: "Invalid URL"}"/>
</expression-transformer>
</otherwise>
</choice>
</flow>

Resources