3 Replies Latest reply on Aug 3, 2012 3:27 PM by dward

    How to use SOAP contextMapper

    mike.daleiden

      The documentation for the OOTB SOAP contextMapper is confusing. I would like to be able to set up a reference to a SOAP-based service that expects the a SOAP message such as the following:

       

      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

                        xmlns:web="http://service.thirdparty.com/webservices"

                        xmlns:dta="http://service.thirdparty.com/webservices/schemas/DTAuthHeader"

                        xmlns:loc="http://service.thirdparty.com/webservices/schemas/LocationWebservice">

         <soapenv:Header>

            <web:DTAuthHeader>

               <dta:username>a_username</dta:username>

               <dta:password>a_password</dta:password>

            </web:DTAuthHeader>

         </soapenv:Header>

         <soapenv:Body>

            <web:LocateDeviceRequest>

               <loc:companyID>someID</loc:companyID>

               <loc:serialID>someSerialID</loc:serialID>

            </web:LocateDeviceRequest>

         </soapenv:Body>

      </soapenv:Envelope>

       

      How would I configure the contextMapper and how do I populate the username and password values?

        • 1. Re: How to use SOAP contextMapper
          dward

          You have two options...

           

          1) Use the OOTB SOAPContextMapper:

           

          a) First, make sure you have this in your switchyard.xml:

           

          <binding.soap>

              <contextMapper includes="{http://service.thirdparty.com}DTAuthHeader" soapHeadersType="XML"/>

          </binding.soap>

           

          b) Then, somewhere in your code, you can add a Context property with a name matching that includes, and a value of an XML String (make sure your soapHeadersType is set to "XML" for that), a DOM Node, or a Configuration object. The root of the value tree would be that same name, and it needs to be added to the Context at Scope.EXCHANGE.  The context mapper will then add it for you.

           

          2) Write your own ContextMapper:

           

          a) First, make sure you have this in your switchyard.xml:

           

          <binding.soap>

              <contextMapper class="com.mycompany.myapp.MyContextMapper"/>

          </binding.soap>

          b) Then, write your own org.switchyard.component.common.composer.ContextMapper implementation.  I would suggest extending BaseContextMapper for ease.

           

          Hope this helps,

          David

          • 2. Re: How to use SOAP contextMapper
            dward

            To give you a couple code samples for 1b above:

             

            import java.io.StringReader;
            
            import javax.xml.namespace.QName;
            
            import org.switchyard.Context;
            import org.switchyard.Scope;
            import org.switchyard.config.Configuration;
            import org.switchyard.config.ConfigurationPuller;
            import org.switchyard.internal.DefaultContext;
            
            public class Test {
                public static void main(String[] args) throws Exception {
                    // IMPORTANT: you would actually call exchange.getContext() in your code.
                    Context context = new DefaultContext();
                    final String key = "{http://service.thirdparty.com/webservices}DTAuthHeader";
            
                    // using SOAPHeadersType.XML
                    String xml = "<web:DTAuthHeader xmlns:web='http://service.thirdparty.com/webservices' xmlns:dta='http://service.thirdparty.com/webservices/schemas/DTAuthHeader'><dta:username>a_username</dta:username><dta:password>a_password</dta:password></web:DTAuthHeader>";
                    xml = xml.replaceFirst("a_username", "kermit").replaceFirst("a_password", "thefrog");
                    context.setProperty(key, xml, Scope.EXCHANGE);
            
                    // using SOAPHeadersType.CONFIG
                    xml = "<web:DTAuthHeader xmlns:web='http://service.thirdparty.com/webservices' xmlns:dta='http://service.thirdparty.com/webservices/schemas/DTAuthHeader'><dta:username/><dta:password/></web:DTAuthHeader>";
                    Configuration config = new ConfigurationPuller().pull(new StringReader(xml));
                    // unqualified child
                    config.getFirstChild("username").setValue("miss");
                    // qualified child
                    config.getFirstChild(QName.valueOf("{http://service.thirdparty.com/webservices/schemas/DTAuthHeader}password")).setValue("piggy");
                    context.setProperty(key, config, Scope.EXCHANGE);
                }
            }
            
            

             

            ...and I'm sure you can figure out how to do a DOM example.

            • 3. Re: How to use SOAP contextMapper
              dward

              Just a note on the above... In a Bean Service scenario, you can have the SwitchYard Context injected into your bean at time of service execution.  That will give you the access to the Context you need.  Please see the "SwitchYard Context Injection" section in the Bean Services docs.