Until-Successful failureExpression condition not working - mule

I created a simple flow which creates a list of names transforms it. The transformer throws an IllegalArgumentException to break the flow. Unfortunately, the failureExpression does not work even though an exception is thrown. It doesn't match any exceptions. I have included the flow and the transformer.
Here is my configuration:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
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" xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/scripting
http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.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/vm
http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/http
http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<spring:beans>
<spring:bean name="transf" class="com.until.sucessful.tests.StringAppenderTransformer" />
<spring:bean id="objectStore" class="org.mule.util.store.SimpleMemoryObjectStore" />
</spring:beans>
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration" />
<flow name="untilsuccessfultestsFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/mytest" doc:name="HTTP" />
<splitter expression="#[xpath3('//Names')]" doc:name="Splitter" />
<until-successful maxRetries="5" millisBetweenRetries="5000" doc:name="Until Successful" objectStore-ref="objectStore" failureExpression="#[exception is java.lang.IllegalArgumentException)]">
<vm:outbound-endpoint path="process-vm" exchange-pattern="request-response" />
</until-successful>
<logger level="INFO" message="After the scoped processor :: #[payload]" doc:name="Logger" />
</flow>
<flow name="processorFlow">
<vm:inbound-endpoint path="process-vm" exchange-pattern="request-response" />
<logger level="INFO" message="Before component #[payload]" doc:name="Logger" />
<transformer ref="transf" />
</flow>
</mule>
Here is my Transformer
public class StringAppenderTransformer extends AbstractTransformer {
#Override
protected Object doTransform(Object src, String enc) throws TransformerException {
String payload = (String) src;
List<String> results = new ArrayList<>();
System.out.println("Upon entry in transformer payload is :: " + payload);
System.out.println("About to return from transformer payload is :: " + payload.split("\\s+"));
int i = 1;
for (String args : payload.split("\\s+")) {
System.out.println("" + i + " " + args);
i++;
if (args != null && args.trim().equals("")) {
results.add(args);
} else {
throw new IllegalArgumentException("Break the Flow!!!!!!");
}
}
return results;
}
}

According to documentation :
https://docs.mulesoft.com/mule-user-guide/v/3.5/until-successful-scope
failureExpression
Specifies an expression that, when it evaluated to true, determines
that the processing of one route was a failure. If no expression is
provided, only an exception will be treated as a processing failure.
So 2 options, remove that expression or be sure that the MEL return true. #[exception.causeMatches("java.lang.IllegalArgumentException")]

Related

Getting org.mule.api.expression.ExpressionRuntimeException

Getting org.mule.api.expression.ExpressionRuntimeException on running below snippet in Mule
I have stored value in var1 and var2 as [message.inboundProperties.'http.query.params'.value1] and [message.inboundProperties.'http.query.params'.value2] respectively.
I'm trying to return sum of the parameters passed.
import java.lang.Integer;
int firstValue = Integer.pareseint(flowVars.var1);
int secondValue =Integer.pareseint(flowVars.var2);
int result = firstValue + secondValue;
payload = result
UPDATE: I've resolved the error but now it is concatenating the inputs not adding them. Other operators like *, /, -, etc work fine.
You can try using Mule Expression as: #[2 + 4]
You can try it in the following way using java transformer component. It's working for me.
Below is the main mule xml config file
<?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:spring="http://www.springframework.org/schema/beans"
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:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="tryoutFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/bill" allowedMethods="GET" doc:name="HTTP"/>
<set-variable variableName="var1" value="#[message.inboundProperties.'http.query.params'.value1]" doc:name="var1"/>
<set-variable variableName="var2" value="#[message.inboundProperties.'http.query.params'.value2]" doc:name="var2"/>
<custom-transformer class="org.mule.transformar.Addition" returnClass="java.lang.Integer doc:name="Java">
</custom-transformer>
</flow>
</mule>
And below are the java class which java transformer component use to transform your message. Remember put the java class under src/main/java folder.
org.mule.transformar.Addition
package org.mule.transformar;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.PropertyScope;
import org.mule.transformer.AbstractMessageTransformer;
public class Addition extends AbstractMessageTransformer{
#Override
public Integer transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
// TODO Auto-generated method stub
Integer i1 = Integer.parseInt(message.getProperty("var1", PropertyScope.INVOCATION));
Integer i2 = Integer.parseInt(message.getProperty("var2", PropertyScope.INVOCATION));
Integer returnVal = i1 + i2;
return returnVal;
}
}
You have done everything right, but few Syntax error like Integer.pareseint instead of Integer.parseInt ...
Please refer the following flow to make it work in a easy way:-
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="testFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<set-variable doc:name="Variable" value="#[message.inboundProperties.'http.query.params'.value1]" variableName="var1"/>
<set-variable doc:name="Variable" value="#[message.inboundProperties.'http.query.params'.value2]" variableName="var2"/>
<expression-component doc:name="Expression"><![CDATA[
import java.lang.Integer;
int firstValue = Integer.parseInt(flowVars.var1);
int secondValue = Integer.parseInt(flowVars.var2);
int result = firstValue + secondValue;
payload = result]]></expression-component>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="#['Total '+message.payload]" level="INFO" doc:name="Logger"/>
</flow>
The url to test is :- http://localhost:8081/test/?value1=12&value2=100

Mule ESB: Can not get MEL to access field

I have the following flow, that accepts a JSON object from http, then
converts the JSON object to a standard Object, and then performs
a CHOICE on the object.
Below is the flow:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:json="http://www.mulesoft.org/schema/mule/json" version="EE-3.5.0" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:core="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.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/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
<json:object-to-json-transformer name="Object_to_JSON" doc:name="Object to JSON"/>
<flow doc:name="HelloWorldFlow1" name="HelloWorldFlow1">
<http:inbound-endpoint doc:description="This endpoint receives an HTTP message." doc:name="HTTP" exchange-pattern="request-response" host="localhost" port="8081" contentType="application/json"/>
<json:json-to-object-transformer doc:name="JSON to Object"/>
<choice doc:name="Choice-Determine-Route" tracking:enable-default-events="true">
<when expression="#[payload.uid == 'ABC']">
<set-payload value="#['When ABC case']" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="#['Default case, payload: ' + payload + ', payload.uid: ' + payload.uid]" doc:name="Set Payload"/>
</otherwise>
</choice>
</flow>
</mule>
Below is the test of the flow
C:\curl>type input2.txt
{ "uid" : "ABC" }
C:\curl>curl -H "Content-Type: application/json" -i -d #input2.txt http://localh
ost:8081
Content-Type: application/json
Default case, payload: {"uid":"ABC"}, payload.uid: null
So even though my input2.txt contained:
{ "uid" : "ABC" }
I could not get the following expression to trigger successfully
#[payload.uid == 'ABC']
Now notice the Set Payload expression
#['Default case, payload: ' + payload + ', payload.uid: ' + payload.uid]
... and what it reported:
Default case, payload: {"uid":"ABC"}, payload.uid: null
So it does not seem to recognize payload.uid
How should I reference this in MEL ?
Thanks
Because you haven't defined the returnClass attribute,it will by default return an instance of org.mule.module.json.JsonData - http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/module/json/JsonData.html
So in that case you need to use:
when expression="#[payload.get('UID') == 'ABC']"
If instead you set the transformer to return a map or an object with a uid field you can navigate it using the . notation you tried.
So to make your expression work use:
<json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>

Mule JPA persist is not inserting or updating

I am using Mule JPA module for retrieving and insert/updating data. I can able retrieve data but not able to update the DB. Its giving no errors and as per the log it seems that the record got updated. But :( If I check DB no recorded is getting inserted.
I believe that the transaction is not getting committed.
Please help me how to achieve this issue.
Here is my mflow
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:json="http://www.mulesoft.org/schema/mule/json" 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.4.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.mulesoft.org/schema/mule/jpa"
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/jpa http://www.mulesoft.org/schema/mule/jpa/current/mule-jpa.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
<spring:beans>
<spring:import resource="classpath:applicationContext.xml" />
</spring:beans>
<jpa:config name="Java_Persistence_API" entityManagerFactory-ref="entityManagerFactory" doc:name="Java Persistence API"/>
<flow name="jpa-exampleFlow1" doc:name="jpa-exampleFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<logger message="payload ---->>>> #[payload]" level="INFO" doc:name="Logger"/>
<logger message="#[message.inboundProperties.get("http.relative.path")]" level="INFO" doc:name="Logger"/>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties.get("http.relative.path")=="getContact"]">
<logger message="in GetContact" level="INFO" doc:name="Logger"/>
<component class="com.test.test.GetContact" doc:name="Java"/>
<jpa:query statement="from ContactEO contact where contact.firstName = :firstName" queryParameters-ref="#[payload:]"></jpa:query>
<!-- <jpa:query statement="from ContactEO contact where contact.id = :id" queryParameters-ref="#[payload:]"/> -->
</when>
<when expression="#[message.inboundProperties.get("http.relative.path")=="addContact"]">
<logger message="In AddContact" level="INFO" doc:name="Logger"/>
<component class="com.test.test.AddContact" doc:name="Java"/>
<transactional action="ALWAYS_BEGIN" doc:name="Transactional">
<jpa:persist entity-ref="#[payload:]" config-ref="Java_Persistence_API" />
</transactional>
</when>
</choice>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="payload ---->>>> #[payload]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
Here is my persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
</persistence-unit>
</persistence>
Here is my console log
2014-05-25 23:41:38,533 INFO [org.mule.api.processor.LoggerMessageProcessor] - <payload ---->>>> /addContact>
2014-05-25 23:41:38,568 INFO [org.mule.api.processor.LoggerMessageProcessor] - <addContact>
2014-05-25 23:41:38,586 INFO [org.mule.api.processor.LoggerMessageProcessor] - <In AddContact>
Hibernate: insert into contact (EMAIL, FIRSTNAME, LASTNAME) values (?, ?, ?)
2014-05-25 23:41:38,811 INFO [org.mule.api.processor.LoggerMessageProcessor] - <payload ---->>>> {"firstName":"king","lastName":"verma","email":"vermaS#xxx.com","id":9}>
Here your console shows :- Hibernate: insert into contact (EMAIL, FIRSTNAME, LASTNAME) values (?, ?, ?) and your payload is :- {"firstName":"king","lastName":"verma","email":"vermaS#xxx.com","id":9} ... where this id:"9" will be accommodated ? your query has 3 fields firstname,lastname and email ..where as your payload contains firstname,lastname,email and id
Finally could able to commit transaction using MULE JPA transport, by creating CustomTransactionFactory which starts the transaction.
public class CustomTransactionFactory implements TransactionFactory{
#Override
public Transaction beginTransaction(MuleContext muleContext)
throws TransactionException {
EntityManagerFactory emf = muleContext.getRegistry().lookupObject("entityManagerFactory");
TransactionFactory tf = new JPATransactionFactory();
Transaction tx = tf.beginTransaction(muleContext);
tx.bindResource(emf, emf.createEntityManager());
tx.begin();
return tx;
}
#Override
public boolean isTransacted() {
return true;
}
}
By referring custom transaction manager in In-bound endpoint as below, we can achieve flow level transactions.
<flow name="jpa_exampleFlow1" doc:name="jpa_exampleFlow1">
<http:inbound-endpoint exchange-pattern="request-response" doc:name="HTTP" address="http://localhost:9090/jpa_example">
<custom-transaction action="ALWAYS_BEGIN" factory-ref="transctionManager"/>
Note: Transactional blocks are no more required.

Mule multiple response

I need to send multiple response from a mule flow one to a http endpoint which would be JSON and another to an SMTP endpoint where the recipient receives a custom email. If I use a transformer to transform the json respone which is default both endpoints receive the same custom email format. So how can I send the default JSON response to the http endpoint and the Custom Transformer generated email to the smtp endpoint below is my flow and Custom Transformer
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:smtp="http://www.mulesoft.org/schema/mule/smtp" xmlns:smtps="http://www.mulesoft.org/schema/mule/smtps" xmlns:data-mapper="http://www.mulesoft.org/schema/mule/ee/data-mapper" xmlns:email="http://www.mulesoft.org/schema/mule/email" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:json="http://www.mulesoft.org/schema/mule/json" 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.4.1" 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/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.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/email http://www.mulesoft.org/schema/mule/email/current/mule-email.xsd
http://www.mulesoft.org/schema/mule/ee/data-mapper http://www.mulesoft.org/schema/mule/ee/data-mapper/current/mule-data-mapper.xsd
http://www.mulesoft.org/schema/mule/smtps http://www.mulesoft.org/schema/mule/smtps/current/mule-smtps.xsd">
<data-mapper:config name="json2_to_json" transformationGraphPath="json2_to_json.grf" doc:name="json_to_json"/>
<flow name="jirarestFlow3" doc:name="jirarestFlow3">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="6767" doc:name="HTTP" contentType="application/json"/>
<logger message="This is from hari #[message.payload]" level="DEBUG" doc:name="Logger"/>
<data-mapper:transform config-ref="json2_to_json" doc:name="JSON To JSON"/>
<logger level="DEBUG" doc:name="Logger" message="This is from Data Mapper #[json:fields/priority/id]"/>
<set-variable variableName="myPayload" value="#[json:fields/reporter/emailAddress]" doc:name="tmpPayload"/>
<logger message="MyPayload is #[myPayload]" level="DEBUG" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="9999" path="rest/api/2/issue/" method="POST" user="" password="" contentType="application/json" doc:name="HTTP"/>
<response>
<!--set-variable variableName="responsePayload" value="#[message.payload]" doc:name="respPayload"/-->
<!--http:response-builder doc:name="HTTP Response Builder" contentType="text/plain" status="200"/-->
<!--expression-transformer doc:name="Expression" /-->
<custom-transformer class="org.hhmi.transformer.EmailBodyTransformer" doc:name="Java"/>
<smtps:outbound-endpoint host="smtp.gmail.com" port="465" user="pandalai" password="soapui67" to="#[myPayload]" from="pandalai#gmail.com" subject="Jira Ticket" responseTimeout="10000" mimeType="text/plain" doc:name="SMTP">
<email:string-to-email-transformer doc:name="Email to String"/>
</smtps:outbound-endpoint>
</response>
</flow>
</mule>
Custom Transformer
package org.xxx.transformer;
import org.apache.log4j.Logger;
import org.xxx.dto.JsonBean;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.transformer.AbstractMessageTransformer;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public class EmailBodyTransformer extends AbstractMessageTransformer {
public static Logger logger = Logger.getLogger(EmailBodyTransformer.class);
#Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
// TODO Auto-generated method stub
StringBuffer html = new StringBuffer();
Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();
JsonBean jBean = new JsonBean();
try {
logger.debug("EmailBodyTransformer payload "
+ message.getPayloadAsString());
logger.debug("EmailBodyTransformer class " + message.getClass());
map = mapper.readValue(message.getPayloadAsString(),
new TypeReference<HashMap<String,String>>(){});
jBean.setId(map.get("id"));
jBean.setKey(map.get("key"));
jBean.setSelf(map.get("self"));
System.out.println("EmailBodyTransformer id from map: "+ jBean.getId());
System.out.println("EmailBodyTransformer map: "+ map);
/* html.append("");
html.append("");
html.append("");
html.append("Dear ").append(jBean.getId()).append(" ");
html.append("Thank you for your order. Your transaction reference is: <strong>");
html.append(jBean.getKey()).append("</strong>");
html.append("");*/
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
//return html;
}
}
The <response></response> tags mean, that whatever you put there will be put into your http:inbound-endpoint response. Since smtp is asynchronous, it will be ignored in the response phase, and the block will return whatever it gets from your custom transformer.
The solution is to move the contents inside the <response></response> block into an <async></async> block, so your custom transformer will not interfere with the http response. Inside the <response></response> block you will need just an <object-to-string-transformer> to transform your http:outbound-endpoint into a string.
EDIT:
Move the <object-to-string-transformer> after the http:outbound-endpoint and change your transformer to take String, not input stream. Otherwise the input stream gets closed once either of the two readers reads it. You will not need the <response></response> after this.
Your requirement is exactly what mule-requester-module is based on:
http://java.dzone.com/articles/introducing-mule-requester
example project: https://github.com/mulesoft/mule-module-requester
This module allows you to asynchronously do two things.
Hope this helps

how to retrieve Schema Validation error result in mule-esb

In Mule, am trying to validate a XML against XSD.
In my flow am using schema-validation-filter component nested with in message-filter component and working as expected.
but my question is, if XML fails, how do I capture the error details in logger component and based on results in need to navigate the flow.
Basically am looking for a MEL to print the error description on the console
Note: "returnResult" is set to false, because i need, to do further operations on the XML.
here is my configuration Flow:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:jms="http://www.mulesoft.org/schema/mule/jms" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" 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.4.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/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.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/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<mulexml:schema-validation-filter schemaLocations="D:\MuleStudio\workspace\exceptiontest\src\test\resources\sample.xsd" returnResult="false" name="Schema_Validation" doc:name="Schema Validation"/>
<flow name="ExceptionTestFlow2" doc:name="ExceptionTestFlow2">
<http:inbound-endpoint exchange-pattern="one-way" host="localhost" port="8081" path="dataQ" doc:name="HTTP"/>
<expression-filter expression="#[message.payload != '/favicon.ico' ]" doc:name="Expression does't allow /favicon.ico"/>
<set-payload value="<data>
<books>
<book edition='1.0'>
<auth> auth</auth>
<title>title</title>
<pulbisher>pub</pulbisher>
</book>
</books>
</data>
" doc:name="XML is set as payload tp the current flow"/>
<logger message="::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Actual Flow Started :::::::::::::::::::::::::::::::::::::::::::::::::" level="INFO" doc:name="indicates Actual Flow Started Logger"/>
<logger message="paylad is :::: #[payload] :::::" level="INFO" doc:name="Prints current Payload"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="dataQ" doc:name="VMQ_stores current xml which needs to be validated_senderQ"/>
</flow>
<flow name="ExceptionTestFlow1" doc:name="ExceptionTestFlow1">
<vm:inbound-endpoint exchange-pattern="one-way" path="dataQ" doc:name="VMQ_stores current xml which needs to be validated_receiverQ"/>
<logger message="::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Flow Started :::::::::::::::::::::::::::::::::::::::::::::::::" level="DEBUG" doc:name="indicates Flow Started Logger"/>
<message-filter doc:name="filter to validate xml against xsd" throwOnUnaccepted="true">
<filter ref="Schema_Validation"/>
</message-filter>
<logger message=" validation is true and the payload is :::: #[payload]" level="INFO" doc:name="current Payload"/>
<logger message="::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: End of Actual Flow:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" level="INFO" doc:name="indicates Flow End Logger"/>
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy when="exception.causedBy(org.mule.api.routing.filter.FilterUnacceptedException)" enableNotifications="false" doc:name="FilterUnacceptedException">
<logger message="::::::::::::::::::::::::::::::::::: in FilterUnacceptedException :::::::::::::::::::::::::" level="ERROR" doc:name="indicates FilterUnacceptedException Flow Started Logger"/>
<set-payload value="The request cannot be processed, the error is #[exception.getMessage()]" doc:name="Set Payload"/> <!-- [1] -->
<set-property propertyName="http.status" value="500" doc:name="Property"/>
<logger message=":::::::::::: end of FilterUnacceptedException with a payload as #[message.payload] ::::::::::::" level="INFO" doc:name="indicates FilterUnacceptedException End Logger"/> <!-- [2] -->
</catch-exception-strategy>
<catch-exception-strategy enableNotifications="false" doc:name="default">
<logger message=":::::::::::::::::::::: in default::::::::::::::::::::::::::::" level="ERROR" doc:name="indicates defaultException Flow Started Logger"/>
<set-payload value="The request cannot be processed, the error is #[exception.getSummaryMessage()]" doc:name="Set Payload"/>
<logger message="::::::::::::::::::::::::::::::::::::::::::::: END of Default Exception :::::::::::::::::::::::::::::::::::" level="INFO" doc:name="indicates DefaultException End Logger"/> <!-- [1] -->
<!-- [2] -->
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
<flow name="Flow_If_XML_not_valid" doc:name="Flow_If_XML_not_valid">
<logger message=":::::::::::::::::::::::::::: #[payload] :::::::::::::: onThrow ::::::" level="INFO" doc:name="Should Print error description"/>
</flow>
</mule>
Have added an exception strategy that gives the following output:
Message has been rejected by filter. Message payload is of type: String
Code : MULE_ERROR--2
Exception stack is:
1. Message has been rejected by filter. Message payload is of type: String (org.mule.api.routing.filter.FilterUnacceptedException)
... http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/routing/filter/FilterUnacceptedException.html)..
I need to be able to pinpoint which field is causing the problem.
Since the filter is configured to throw on unaccepted, you need to have an exception strategy in place in order to deal with the error.
Read: http://www.mulesoft.org/documentation/display/current/Error+Handling
You don't, see the SchemaValidationFilter source file. The SAXException is just catch and log (in debug). I think you need make your own SchemaValidationFilter. (Inherit Mule Validator)
package what.the.fuck.customFilter;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import org.mule.api.MuleMessage;
import org.mule.api.transport.PropertyScope;
import org.mule.module.xml.filters.SchemaValidationFilter;
import org.xml.sax.SAXException;
public class SchemaValidationFilterWithTrace extends SchemaValidationFilter {
public final static String SAX_ERROR_PROPERTIES = "SAX_ERROR_PROPERTIES";
public final static boolean RETURN_RESULT = false;
public final static String SCHEMA_LOCATION = "what.the.fuck.xsd";
public SchemaValidationFilterWithTrace(){
super();
super.setReturnResult(false);
super.setSchemaLocations(SCHEMA_LOCATION);
}
/**
* Accepts the message if schema validation passes.
*
* #param message The message.
* #return Whether the message passes schema validation.
*/
#Override
public boolean accept(MuleMessage message)
{
Source source;
try
{
source = loadSource(message);
}
catch (Exception e)
{
if (e instanceof RuntimeException)
{
throw (RuntimeException) e;
}
if (logger.isInfoEnabled())
{
logger.info("SchemaValidationFilter rejected a message because there was a problem interpreting the payload as XML.", e);
}
return false;
}
if (source == null)
{
if (logger.isInfoEnabled())
{
logger.info("SchemaValidationFilter rejected a message because the XML source was null.");
}
return false;
}
DOMResult result = null;
try
{
if (super.isReturnResult())
{
result = new DOMResult();
createValidator().validate(source, result);
}
else
{
createValidator().validate(source);
}
}
catch (SAXException e)
{
message.setProperty(SAX_ERROR_PROPERTIES, e.getMessage(), PropertyScope.OUTBOUND);
if (logger.isDebugEnabled())
{
logger.debug(
"SchemaValidationFilter rejected a message because it apparently failed to validate against the schema.",
e);
}
return false;
}
catch (IOException e)
{
if (logger.isInfoEnabled())
{
logger.info(
"SchemaValidationFilter rejected a message because there was a problem reading the XML.",
e);
}
return false;
}
finally
{
if (result != null && result.getNode() != null)
{
message.setPayload(result.getNode());
}
}
if (logger.isDebugEnabled())
{
logger.debug("SchemaValidationFilter accepted the message.");
}
return true;
}
}