4 Replies Latest reply on Jan 17, 2015 2:54 AM by mageshbk

    SOAPFault breaks route

    moraleslos

      In my SwitchYard application I have a SOAP reference to an external web service.  For some reason, every time the external SOAP service returns a SOAPFault, the camel route breaks and throws an Exception (Internal 500 error).  However the exception message contains the actual fault xml message.  I have a processor (called addressServiceSoapProcessor shown below) referenced after the call to the SOAP service but that processor never gets invoked.  I was hoping to catch that fault exception in the processor, create a different message, and return that message back to the calling service (AddressService).  My route looks like this:

       

      <routes xmlns="http://camel.apache.org/schema/spring">

          <route>

              <from uri="switchyard://AddressService"/>

              <process ref="addressServiceProcessor"/>

              <log message="AddressService - message received: ${body}"/>

              <to uri="switchyard://AddressSoapServicePortType"/>

              <process ref="addressServiceSoapProcessor"/>

          </route>

      </routes>

       

      I've been looking at try/catch and onexceptions for the routes but they seem to all require to route to another destination (i.e. to uri="somewhere_else") when catching the exception.  I don't want to route it anywhere else.  I just want to be able to catch the fault exception, extract the fault code, and then return a message that contains this fault code back to the calling service (i.e. synchronous call).

       

      Any ideas on how to do this with SwitchYard?

        • 1. Re: SOAPFault breaks route
          jorgemoralespou_2

          Hi,

          If you use something like this:

          onException(Exception.class)
            .log("TODO: Generate response Error occuring while validating xml ")
            .setFaultBody(method(ExceptionHandler.class,"createSoapFault")).handled(true).end();
          

           

          When an Exception is thrown, an Exception handlers catches that Exception. If you want to provide with a response and follow the execution you should set handled, otherwise, it will break the execution back to the caller (as any exception).

           

          If you want to modify the contents of the body, you can do it in the onException like above, and then decide whether you want to mark it as handled or not.

           

          Hope it helps,

          1 of 1 people found this helpful
          • 2. Re: SOAPFault breaks route
            moraleslos

            Is there a way to do the above using the xml dsl or must this only be done using camel java code?

             

            Also is your exceptionHandler class you described-- does this actually implement ExceptionHandler from camel or is this just a user-defined POJO?

            • 3. Re: SOAPFault breaks route
              moraleslos

              Well I tried the java dsl version below (using an example from camel + combining with Jorge's response above) and I still get the same issue.  Its like it ends at the AddressSoapServicePortType:

               

              public void configure() {

                from("switchyard://AddressService")

                .processRef("addressServiceProcessor")

                .log("Received message for 'AddressService' : ${body}")

                .to("switchyard://AddressSoapServicePortType")

                .onException(Exception.class)

                .log("TODO: Generate response Error occuring while validating xml")

                .process(new AddressServiceSoapProcessor()).handled(true).end();

                }

               

              I don't see any logs showing ("TODO: Generate..."), my processor is not being invoked-- the route just ends when I get the fault.

              • 4. Re: SOAPFault breaks route
                mageshbk

                You will need to add handleFault to catch the exception and process the SOAPFault.

                 

                    <route handleFault="true">
                        <from uri="switchyard://AddressService"/>
                        <process ref="addressServiceProcessor"/>
                        <log message="AddressService - message received: ${body}"/>
                        <doTry>
                            <to uri="switchyard://AddressSoapServicePortType"/>
                            <process ref="addressServiceSoapProcessor"/>
                            <doCatch>
                                <exception>java.lang.Exception</exception>
                                <to uri="log:xml?level=WARN"/>
                                <process ref="addressServiceSoapFaultProcessor"/>
                            </doCatch>
                        </doTry>
                    </route>
                
                

                 

                In the addressServiceSoapFaultProcessor, you can retrieve the fault as shown below:

                Exception e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
                SOAPFaultInfo fault = exchange.getProperty(SOAPComposition.SOAP_FAULT_INFO, SOAPFaultInfo.class);
                
                

                addressServiceSoapFaultProcessor