4 Replies Latest reply on Aug 15, 2014 11:31 AM by mh1

    How to trigger custom SOAP interceptor?

    mh1

      The Problem:


      We've built a web-service using SwitchYard running on Fuse Service Works. (jboss-fsw-6.0.0.GA-redhat-4) When an invalid XML request to our web-service is received, we want to be able to customise the text in the SOAP Fault message sent in response. At the current time, the actual response sent out is produced by the Soap12FaultOutInterceptor and contains a message that describes the problem - be it a missing tag, an empty request or whatever. We've been tasked with consolidating all such responses to send a standard message of "Message Format Invalid" hence the motivation to pursue this.

       

      Our Attempted Solution:

       

      To do this, we've created a custom interceptor (via the '<class> extends AbstractSoapInterceptor' route) and used the constructor to set the phase in the interceptor chain that our custom interceptor is inserted. We've implemented the 'handleMessage' method with a simple LOG/SYSO message for testing while we develop this. We've declared this interceptor on the SOAP binding of our SwitchYard diagram and confirmed it produced the expected XML config in the switchyard.xml file.

       

      Here's some examples of the code produced to illustrate:

       

      Config that appears in the switchyard.xml file after we add our interceptor to the SOAP binding.

       

      <soap:binding.soap name="OurWebServiceSoapBinding">

        <soap:contextMapper soapHeadersType="DOM"/>

        ...<snip>...

       

      <soap:outInterceptors>

         <soap:interceptor class="com.ourweb.service.bean.interceptor.MessageFormatInvalidOutFaultInterceptor"/>

      </soap:outInterceptors>

      </soap:binding.soap>

       

      The custom interceptor we created:

       

      public class MessageFormatInvalidOutFaultInterceptor extends AbstractSoapInterceptor

      {

        /** Logger Constant - Represents the log-instance to use when logging messages. */

        private static final Logger LOG = LoggerFactory.getLogger(MessageFormatInvalidOutFaultInterceptor.class);

       

        public MessageFormatInvalidOutFaultInterceptor()

        {

          super(Phase.INVOKE);

      getAfter().add(Soap12FaultOutInterceptor.class.getName());

        }

       

        public void handleMessage(SoapMessage message) throws Fault

        {

          // Fault fault = (Fault) message.getContent(Exception.class);

          Fault fault = message.getContent(Fault.class);

       

          LOG.debug("########## -> MessageFormatInvalidOutFaultInterceptor!!!");

          LOG.debug("########## -> [" + fault.getDetail().getFirstChild().getTextContent() + "]");

       

          System.out.println("########## -> MessageFormatInvalidOutFaultInterceptor!!!");

          System.out.println("########## -> [" + fault.getDetail().getFirstChild().getTextContent() + "]");

        }

      }


      Note: We've tried testing this at each of the phases in the chain (here quoted it's INVOKE but really we'd have thought this should be around PREPARE_SEND) and we've added the 'getAfter' in a final bid of desperation!


      No matter what we do, we cannot get a request message sent into our web-service to trigger this interceptor.


      Thus, we're rather stuck for ideas and would be grateful if anyone can lend some thoughts or advice on things we may need to do/try/test. This is our/my first time working with this technology stack so we're learning as we go.


      Many thanks in advance.


      Mark.

        • 1. Re: How to trigger custom SOAP interceptor?
          kcbabo

          Are you saying the interceptor is not triggered on the happy and error paths?  Or is the issue that it's not triggered on the error (invalid message) path only?

          • 2. Re: How to trigger custom SOAP interceptor?
            mh1

            The interceptor was certainly triggered on both happy and error paths.

             

            To give a better insight, here are the three prefix declarations I made in the interceptor:

             

                  namespacePrefixes.put("billybobthornton","http://www.w3.org/2003/05/soap-envelope");

                  namespacePrefixes.put("eps","http://www.my.web.address.uk");

                  namespacePrefixes.put("myprojectname","urn:com.aoa.myprojectname:myprojectname:1.0.0");

             

            And here is the content of the happy path response message:

             

            <billybobthornton:Envelope xmlns:billybobthornton="http://www.w3.org/2003/05/soap-envelope" xmlns:myprojectname="urn:com.aoa.myprojectname:myprojectname:1.0.0" xmlns:eps="http://www.my.web.address.uk">

               <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope">

                  <urn:ExchangeHeader xmlns:urn="urn:com.aoa.myprojectname:myprojectname:1.0.0">

                     <!-- Header Content Appears Here -->

                  </urn:ExchangeHeader>

               </env:Header>

               <billybobthornton:Body>

                  <MyWebServiceResponse xmlns="urn:com.aoa.myprojectname:myprojectname:1.0.0">

                     <ns2:MyWebServiceResponseEnv SchemaVersion="1.0" xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:ns2="http://www.my.web.address.uk">

                       <!-- Body Content Appears Here -->

                     </ns2:MyWebServiceResponseEnv>

                  </MyWebServiceResponse>

               </billybobthornton:Body>

            </billybobthornton:Envelope>

             

            Here the soap-envelope name-space prefix gets redefined in the envelope's Header element. Meanwhile, the prefixes selected for our project name-space have been changed to make one the default name-space and the other is assigned the prefix 'ns2'.

             

            And here is the content of the error path response message:

             

            <billybobthornton:Envelope xmlns:billybobthornton="http://www.w3.org/2003/05/soap-envelope" xmlns:myprojectname="urn:com.aoa.myprojectname:myprojectname:1.0.0" xmlns:eps="http://www.my.web.address.uk">

               <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope"/>

               <billybobthornton:Body>

                  <env:Fault xmlns:env="http://www.w3.org/2003/05/soap-envelope">

                     <env:Code>

                        <env:Value>env:Sender</env:Value>

                     </env:Code>

                     <env:Reason>

                        <env:Text xml:lang="en-GB">Message Format Invalid</env:Text>

                     </env:Reason>

                  </env:Fault>

               </billybobthornton:Body>

            </billybobthornton:Envelope>

             

            Here - there's only the redefining the prefix for the soap-envelope name-space that is of concern.

            • 3. Re: Re: How to trigger custom SOAP interceptor?
              kcbabo

              I think maybe we are crossing wires on the two forum threads you started (one in SY forum and one in the FSW forum).  In this thread, you said:

              Sopra Mark-H wrote:

              No matter what we do, we cannot get a request message sent into our web-service to trigger this interceptor.

               

              Your other thread (in the FSW forum) dealt with setting the namespace prefix for header elements.  So have we passed the issue of the interceptor not being triggered and now the namespace problem is the only issue remaining?

              • 4. Re: Re: How to trigger custom SOAP interceptor?
                mh1

                Hi Keith - really sorry - was not paying close enough attention to the thread I was in.

                 

                The interceptor triggering issue was raised some time ago and I finally managed to get that interceptor to trigger by inserting it at the PHASE_RECEIVE point - that was an interceptor for changing the Text field of the Reason element in the Soap Fault because our client expected the text to be of the form...

                 

                <env:Text xml:lang="en-GB">Message Format Invalid</env:Text>

                 

                ... and whenever I had inserted the interceptor at a later stage in the interceptor stack, it didn't seem to trigger. In this case, we were testing with empty/null messages and messages that didn't validate against the schema so we weren't expecting our service beans to get called since SY seems to be able to reject the message and produce the soap fault response automatically.

                 

                More recently, we were asked to investigate the issue with the prefixes which was what led to the other post. I think our client is also working on making their system prefix-agnostic as it should be but I was surprised when I couldn't bend our response messages to our will using the interceptor based on what I'd read. As noted, I've not worked on this tech stack before or with web-services so each step is a new lesson learned typically.