Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Creating CXF Interceptor in Mule (3.9)

DZone's Guide to

Creating CXF Interceptor in Mule (3.9)

Read this article in order to view a tutorial on how to gain access to the underlying SOAP fault when a SOAP exception happens when working on creating Mule applications.

· Integration Zone ·
Free Resource

The new Gartner Critical Capabilities report explains how APIs and microservices enable digital leaders to deliver better B2B, open banking and mobile projects.

Overview

When working on creating Mule applications that connect to SOAP web services, developers will often find that they need to have access to the underlying SOAP fault when a SOAP exception happens. This article will demonstrate how this can be achieved by creating a CXF interceptor.

There are two parts to this article. The first part will talk about how to create the mock soap service, and the second part will talk about creating the Mule app that implements the interceptor. The reason I have created the Mock SOAP service is that I want to prove that the recommended steps work and they are not merely theoretical suggestions.

I came to know about intercepting Mule Soap calls while working on the following issue:

Creating the Mock SOAP Service

The source code for the mock SOAP service is provided in the links at section 1.0, you just need to git clone the code and run the following maven command.

 mvn clean package 

Once this is done, you will now be able to run the SOAP web service. While inside the project folder, run the following command.

java -cp .\target\CCCJavaSoapMocker-0.0.1-SNAPSHOT.jar com.kian.mock.soap.service.Main


This command will start up the SOAP web service. To verify that the soap service has started, browse to the following URL on your local machine:

http://localhost:8080/WS/MockService?wsdl

I have used the port 8080 for the mock SOAP service. Feel free to change it from the source code, recompile it, and run it. If the mock soap service is running, you will see the following results when you browse to the following wsdl URL (Figure 2.0a).

Figure 2.0a

Creating the Custom CXF Interceptor

There are 2 things you need to do to create the custom CXF interceptor. Step 1 is to create the interceptor java class (the implementation) and the next step to is to create the cxf.xml file that intercepts and diverts SOAP service calls to the class.

Then, the interceptor is implemented, and it divers all SOAP calls in your mule application to the interceptor, if you are only interested in intercepting certain SOAP service calls, you need to implement that locally. This article will show you how to implement it globally.

The source code for the Mule application that has this global CXF Interceptor implementation is provided in the links mentioned in section 1.0.

3.1 Creating the Custom CXF Interceptor Class

The custom interceptor class that is created is located in the following package.

 com.kian.cxf.interceptor 

Let's zoom in on the following method because this is the meat of the whole intercepting mechanism. This is the method that will be used to get the SOAP fault.

@Override
        public void handleMessage(SoapMessage message) throws Fault {
                  InputStream is = (InputStream) message.getContent(InputStream.class);
                  ByteArrayOutputStream os = new ByteArrayOutputStream();
                  try {
                        IOUtils.copy(is, os);
                  } catch (IOException e) {
                        log.error("SoapFaultInterceptor.handleMessage", e);
                  }
                  InputStream newIs = new ByteArrayInputStream(os.toByteArray());
                  message.setContent(InputStream.class, newIs);

                  MuleEvent event = (MuleEvent)

                           message.getExchange().get(org.mule.module.cxf.CxfConstants.MULE_EVENT);

                  event.getMessage().setInvocationProperty("OriginalPayload",os.toString());
                  log.info("Intercepting completed !!!!");
        }

Listing 3.1a

I need you to pay attention to the first line of the code statement in the method; and it is getting InputStream from the SOAPMessage. This method implementation is specifically for “cxf:inInterceptors” and “cxf:inFaultInterceptors”, (if you use it for “cxf:outInterceptors” or cxf:outFaultInterceptors you will get errors because “message.getContent(InputStream.class)” will return null). This interceptor merely copies the intercepted soap payload into a flow variable called “OriginalPayload.”

3.2 Creating the CXF Interceptor Global Configuration

Now, once the java implementation for the CXF interceptor is complete, we are ready to configure the global CXF interceptor file. This file will be created in the src/main/resource folder.

The following is the contents in the file.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:cxf="http://cxf.apache.org/core" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd 
                       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <bean class="com.kian.cxf.interceptor.CustomInterceptor" 

                id="customInterceptor" />
        <cxf:bus>
                <cxf:inInterceptors>
                        <ref bean="customInterceptor" />
                </cxf:inInterceptors>
        </cxf:bus>
</beans>

In the configuration file, you will need to create a spring bean entry referring to the java class we have previously created in section 3.1 and will later refer to the bean in the “cxf:inInterceptors” configuration (as shown in the snippet).

Your Mule project folder should look like the following format (Figure 3.2 a). Notice the location of the cxf.xml file.

Figure 3.2a

Your Mule application would look like the following:

Figure 3.2b

The Mule app starts to set two numbers a and b and then assigns these numbers to the SOAP payload that will be used to invoke the mock SOAP service. As mentioned earlier, the SOAP service merely conducts a division between “a” and “b.” If you assign “b” with a zero(0), you will get a divide by zero SOAP fault.

The set payload message processor is used to set the flow variable called “OriginalPayload” as the payload. This is because the java interceptor code (mentioned in Listing 3.1a) gets the payload that is passing through the interceptor and sets it in a flow variable called a similar name.

4.0 Conclusion

Now that we have the Mule application built, it is time to test the interceptor and run the Mule application in debug mode. Once the Mule app is running in debug mode, use Google Chrome and browse to the following URL:

http://localhost:8081/test

If you step through the debugger, you will see that the following values for the flow variables are being passed as part of the web service payload (Figure 4.0a). This will create a SOAP fault because we are trying to divide 1 with zero (0).

Figure 4.0a

If you step through the debugger, it will also stop at the breakpoints that you have set in the interceptor java code (Figure 4.0b).

Figure 4.0b

The last statement in the interceptor method logs an “Intercepting completed!!!!” complete message. You will see that the interceptor method will only be executed once because in your log you will only see one entry (Figure 4.0c).

Figure 4.0c

SoapFaults will come back to Mule as exception (Figure 4.0d). Notice the red dotted square (during debug mode) indicating an exception has been thrown (an error has occurred).

Figure 4.0d

When exception occurs during a SOAP fault, the SOAP fault payload would be lost when its execution control is passed to “Catch Exception Strategy,” but we have used the intercepting java code to set the intercepted soap fault payload into a flow var, and in the catch exception strategy, we have a set payload message processor to set the flow variable named “OriginalPayload” as the payload. This is so that the SOAP fault would be bubbled up into Mule for later manipulation or display.

If the implementation is successful, you will see the following response when you do a get on the Mule app URL (Figure 4.0a).

Figure 4.0a

The new Gartner Critical Capabilities for Full Lifecycle API Management report shows how CA Technologies helps digital leaders with their B2B, open banking, and mobile initiatives. Get your copy from CA Technologies.

Topics:
mulesoft ,cxf ,soap ,webservice ,interceptor ,mule 3.9 ,mule

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}