I found a solution using TransformerException and CXF OutFaultInterceptor.
My approach is as follows:
Write a custom transformer class inside which add the validation rules. For example, if I want to throw Error for Integer a or b being null, I will add a Custom Transformer AddValuesBusinessLogic.class with the following code:
public class AddValuesBusinessLogic extends AbstractMessageTransformer
{
@Override
public Object transformMessage(MuleMessage message, String outputEncoding) throws
TransformerException
{
MuleMessage muleMessage = message;
AddValues addValues = (AddValues) muleMessage.getPayload();
if (addValues.getA() == null || addValues.getB() == null ) {
//Make an AddValueException object
throw new TransformerException(this,new AddValueException("BAD REQUEST"));
}
return "ALL OK";}
This exception will then propagate to CXF where I am writing an OutFaultInterceptor like follows:
public class AddValuesFaultInterceptor extends AbstractSoapInterceptor {
private static final Logger logger = LoggerFactory.getLogger(AddValuesFaultInterceptor.class);
public AddValuesFaultInterceptor() {
super(Phase.MARSHAL);
}
public void handleMessage(SoapMessage soapMessage) throws Fault {
Fault fault = (Fault) soapMessage.getContent(Exception.class);
if (fault.getCause() instanceof org.mule.api.transformer.TransformerMessagingException) {
Element detail = fault.getOrCreateDetail();
Element errorDetail = detail.getOwnerDocument().createElement("addValuesError");
Element errorCode = errorDetail.getOwnerDocument().createElement("errorCode");
Element message = errorDetail.getOwnerDocument().createElement("message");
errorCode.setTextContent("400");
message.setTextContent("BAD REQUEST");
errorDetail.appendChild(errorCode);
errorDetail.appendChild(message);
detail.appendChild(errorDetail);
}
}
private Throwable getOriginalCause(Throwable t) {
if (t instanceof ComponentException && t.getCause() != null) {
return t.getCause();
} else {
return t;
}
}
}
Now when I make a call using either SOAPUI or jaxws client, I get the custom fault exception in the SOAP response.
To extract the values of errorCode and errorMessage in JAXWS client I am doing the following in the catch block of try-catch:
catch (com.sun.xml.ws.fault.ServerSOAPFaultException soapFaultException) {
javax.xml.soap.SOAPFault fault = soapFaultException.getFault(); // <Fault> node
javax.xml.soap.Detail detail = fault.getDetail(); // <detail> node
java.util.Iterator detailEntries = detail.getDetailEntries(); // nodes under <detail>'
while(detailEntries.hasNext()) {
javax.xml.soap.DetailEntry detailEntry = (DetailEntry) detailEntries.next();
System.out.println(detailEntry.getFirstChild().getTextContent());
System.out.println(detailEntry.getLastChild().getTextContent());
}
}
This is working for me as of now.
However I will request suggestionsto improve on this workaound or if there are any better solutions.
Thanks everyone.