Omgo's Blog

December 31, 2009

Proxying webservices with Mule (including Faults)

Filed under: Mule ESB — aswin @ 12:16 am

In one of my current projects we are using Mule as our esb of choice.  Coming from Apache Camel background, I found the xml configuration a bit too verbose. Its definitely much intuitive and easy to write your routes using a DSL than using xml for it (camel support both though and I think Mule is getting there with version 3.0).  But I must say the IDE support for XML configuration is getting better in terms of code completion and stuff, but I think DSLs definitely have an edge in such cases.

Anyways getting on to what I really want to write about,   we had a requirement to proxy some web-services in order to deal with certain security and auditing functions.  So the approach was to throw in a cxf endpoint in proxy mode (you could use http or WS Provider etc instead) and route the request to the actual destination service and return the results to the actual caller. The sequence looks like the following

Client  –>   CXF Proxy Endpoint in Mule  –>  all interception activities —> call destination service

Everything worked fine  (of course after bumping into many small issues)  except for the case when the destination service throws a SOAP fault . Mule would treat this event as an exception on the route and would cause a empty response to be send to the actual client. This blog entry shows how to deal with this scenario and return a custom exception back to the actual caller.

In my case  I wanted to return the actual fault returned by the destination service to  the original client without specifically dealing with the exception (in translating it as in Marios’ solution).   So I took the approach from Marios solution and changed the error handler to the following

import org.apache.cxf.binding.soap.SoapFault;
import org.mule.api.ExceptionPayload;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.message.DefaultExceptionPayload;
import org.mule.transformer.AbstractMessageAwareTransformer;

/**
* attribution : http://marioklaver.blogspot.com/2009/05/mule-show-me-exception-please.html
*/
public class ErrorTransformer extends AbstractMessageAwareTransformer {
// private ExceptionHandlerStrategy exceptionHandlerStrategy;

@Override
public Object transform(MuleMessage message, String outputEncoding) throws TransformerException {
if (message.getExceptionPayload() != null) {
ExceptionPayload exceptionPayload = message.getExceptionPayload();
Throwable e = exceptionPayload.getException();
e = unwrapCause(e, SoapFault.class);
message.setExceptionPayload(new DefaultExceptionPayload(e));
}
return message;
}

private Throwable unwrapCause(Throwable e, Class<?> exceptionClass) {
Throwable temp = e;
do {
if (exceptionClass.isInstance(temp)) {
return temp;
}
} while ((temp = temp.getCause()) != null && temp != temp.getCause());
return e;
}
}

The main thing this transformer does is to unwrap the actual soap fault from the destination service and place it directly on the exception payload.  The CXF proxy endpoint I had then would be able to take this and return the soap fault xml representation back to original client.

And in mule-config you would have the following.

<spring:beans>
<spring:bean id="ErrorTransformer" />
</spring:beans>

<service name="GenericCXFProxyService">
 <inbound>
 <cxf:inbound-endpoint address="http://localhost:9090/cxfproxy" proxy="true" />
 </inbound>
 <outbound>
 <pass-through-router>
 <outbound-endpoint address="vm://handOff" synchronous="true" />
 </pass-through-router>
 </outbound>
 </service>

<service name="HandOff">
<inbound>
<vm:inbound-endpoint address="vm://handOff" responseTransformer-refs="ErrorTransformer"/>
</inbound>
<component class="xxxxx"> </component>
<outbound>
<pass-through-router>
<cxf:outbound-endpoint address="http://localhost:9090/greetings" synchronous="true" proxy="true" />
</pass-through-router>
</outbound>
</service>

Thats it!! and you now have a proxy that proxies both good and bad responses without much work. Let me know if this is not working for you..

Create a free website or blog at WordPress.com.