5 Replies Latest reply on Feb 11, 2013 6:26 AM by Paul Kristensen

    Camel route endpoint format for external SOAP binding

    Paul Kristensen Newbie

      Hi,

       

      I am trying to expose an existing thirdparty SOAP-based webservice via a REST-based interface ie. sort of REST->SOAP bridge.

      With my current magic level in Switchyard terminology in mind - what I have already is this (deployed in a 0.7 final runtime):

      rest-to-soap-bridge.png

      • a ChangeResource service exposed via a REST binding and corresponding JAXB annotations
      • a Camel route (xml-based) that routes between the two
      • a Reference to the external SOAP service with the WSDL as the interface/contract
      • A java-based transformer to map between the SOAP types and the java ones (not shown in the screenshot)

       

      All of these bits and pieces seem to deploy without any errors:

       

      (...)

      10:06:03,722 INFO  [org.switchyard.common.camel.SwitchYardCamelContext] (MSC service thread 1-1) Route: direct:{urn:dk.jndata.kls:phk-test-soap:1.0}ServiceManagerExternalWebservice started and consuming from: Endpoint[direct://%7Burn:dk.jndata.kls:phk-test-soap:1.0%7DServiceManagerExternalWebservice]

      10:06:03,764 INFO  [org.switchyard.common.camel.SwitchYardCamelContext] (MSC service thread 1-1) Route: route4 started and consuming from: Endpoint[switchyard://RouteService?namespace=urn%3Adk.jndata.kls%3Aphk-test-soap%3A1.0]

      10:06:03,850 INFO  [org.switchyard.common.camel.SwitchYardCamelContext] (MSC service thread 1-1) Route: direct:{urn:dk.jndata.kls:phk-test-soap:1.0}ChangeResource started and consuming from: Endpoint[direct://%7Burn:dk.jndata.kls:phk-test-soap:1.0%7DChangeResource]

      (...)

       

      However when I try to call the REST-service the call gets all the way to the Camel route (I placed a log message in the route.xml to verify this) but then Camel chokes with following:

       

      10:19:55,527 INFO  [route4] (http-localhost-127.0.0.1-8080-2) Route - message received: <chan:getChangeRequest xmlns:chan="http://change.teg.globicon.dk"><chan:getChange><chan:changeId>12345</chan:changeId><chan:userId>MASKED</chan:userId><chan:password>MASKED</chan:password></chan:getChange></chan:getChangeRequest> for operation getChange

      10:19:55,535 ERROR [org.apache.camel.processor.DefaultErrorHandler] (http-localhost-127.0.0.1-8080-2) Failed delivery for (MessageId: ID-WJN00628-10366-1360140433452-4-3 on ExchangeId: ID-WJN00628-10366-1360140433452-4-4). Exhausted after delivery attempt: 1 caught: org.switchyard.HandlerException: org.switchyard.exception.SwitchYardException: No registered service found for {urn:dk.jndata.kls:phk-test-soap:1.0}ServiceManagerExternalWebservice: org.switchyard.HandlerException: org.switchyard.exception.SwitchYardException: No registered service found for {urn:dk.jndata.kls:phk-test-soap:1.0}ServiceManagerExternalWebservice

       

      The route is defined like this:

       

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

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

        <log message="Route - message received: ${body} for operation ${header.org.switchyard.operationName} "/>

        <setHeader headerName="operationName">

                               <simple>${header.org.switchyard.operationName}</simple>

        </setHeader>

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

      </route>

       

      Should I use some other type of camel protocol prefix than "switchyard" in the route in order to access the SOAP service ?

      The external SOAP service should not be registered as a service but as a outbound reference, right?

       

      Here's the switchyard.xml contents:

       

      <switchyard xmlns="urn:switchyard-config:switchyard:1.0" xmlns:bean="urn:switchyard-component-bean:config:1.0" xmlns:camel="urn:switchyard-component-camel:config:1.0" xmlns:resteasy="urn:switchyard-component-resteasy:config:1.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:soap="urn:switchyard-component-soap:config:1.0" xmlns:transform="urn:switchyard-config:transform:1.0" name="phktest-soap" targetNamespace="urn:dk.jndata.kls:phk-test-soap:1.0">

        <sca:composite name="phktest-soap" targetNamespace="urn:dk.jndata.kls:phk-test-soap:1.0">

          <sca:component name="Route">

            <camel:implementation.camel>

              <camel:xml path="route.xml"/>

            </camel:implementation.camel>

            <sca:service name="RouteService">

              <sca:interface.wsdl interface="TegFacadeChange.wsdl#wsdl.porttype(TegFacadeChangePortType)"/>

            </sca:service>

            <sca:reference name="ServiceManagerExternalWebservice">

              <sca:interface.wsdl interface="TegFacadeChange.wsdl#wsdl.porttype(TegFacadeChangePortType)"/>

            </sca:reference>

          </sca:component>

          <sca:reference name="ServiceManagerExternalWebservice" multiplicity="0..1" promote="Route/ServiceManagerExternalWebservice">

            <sca:interface.wsdl interface="TegFacadeChange.wsdl#wsdl.porttype(TegFacadeChangePortType)"/>

          </sca:reference>

          <sca:service name="ChangeResource" promote="Route/RouteService">

            <sca:interface.java interface="dk.jndata.kls.phk_test_soap.ChangeResource"/>

            <resteasy:binding.rest>

              <resteasy:contextMapper/>

              <resteasy:interfaces>dk.jndata.kls.phk_test_soap.ChangeResource</resteasy:interfaces>

              <resteasy:contextPath>phktest-soap</resteasy:contextPath>

            </resteasy:binding.rest>

          </sca:service>

        </sca:composite>

      </switchyard>

       

      Thanks,

      Paul

        • 1. Re: Camel route endpoint format for external SOAP binding
          Keith Babo Master

          Based on IRC discussion, I take it "ServiceManagerExternalWebservice" is provided by another application.  There are two answers here:

           

          1) Today, you can use the same namespace for both applications to get this to work.  This is a bit of a hack to provide inter-application communication without a binding while we worked on 2 ...

          2) We are introducing an extension to binding.sca that allows wiring to other local applications with different namespaces.

           

          Option 1 is the answer for 0.7 and earlier.  Option 2 will be available in 0.8.

           

          @Lukasz : an interesting option 3 here would be to allow a Camel VM binding for the service and reference to communicate.  The user could choose a logical name in the binding definition and just make sure those line up.  I did notice that there's not a binding.vm defined in the camel-core XSD, however.  For now I guess it could be done with the URI binding, but it might be nice to have a specific binding schema.

          • 2. Re: Camel route endpoint format for external SOAP binding
            Paul Kristensen Newbie

            Hi Keith,

             

            Yes, the "ServiceManagerExternalWebservice" is an externally provided SOAP-based webservice - ie. not implemented within the switchyard runtime.

            What I need is something along the lines of letting the route reference the external service as a route endpoint. I thought this was doable using a reference to the external service and then this "No registered service found for" issue popped up.

            Am I missing some sort of registration/promotion of the external reference?

             

            Btw, is there somewhere I can check out the "IRC discussion" you mention?

             

            Cheers,

            Paul

            • 3. Re: Camel route endpoint format for external SOAP binding
              Łukasz Dywicki Novice

              Hey Paul,

              You may call external services in camel route without using switchyard:// prefix and witchtchout service/reference definition in switchyard.xml. In your case you may use camel-cxf directly to call SOAP service.

               

              Camel VM binding will let you call services on local instance, eg. in reference you may put camel:binding.uri configUri="vm:myService" to send messages to queue shared acros whole JVM instance. In another place you may consume messages by usage of camel:binding.uri configUri="vm:myService" inside service definition.

               

              However your case is a bit different since you have only interface and no binding details for reference thus we don't know how to reach service. VM in this case will let you send messages to ServiceManagerExternalWebservice but nobody will consume them.

              • 4. Re: Camel route endpoint format for external SOAP binding
                Keith Babo Master

                Yes, the "ServiceManagerExternalWebservice" is an externally provided SOAP-based webservice - ie. not implemented within the switchyard runtime.

                 

                Ah, in that case you want a SOAP binding for the reference.  If you are using the tooling, just drag a SOAP binding onto the composite reference.  Here's an example of a reference with a SOAP binding:

                 

                https://github.com/jboss-switchyard/quickstarts/blob/master/camel-soap-proxy/src/main/resources/META-INF/switchyard.xml

                 

                 

                Yes, the "ServiceManagerExternalWebservice" is an externally provided SOAP-based webservice - ie. not implemented within the switchyard runtime.

                What I need is something along the lines of letting the route reference the external service as a route endpoint. I thought this was doable using a reference to the external service and then this "No registered service found for" issue popped up.

                Am I missing some sort of registration/promotion of the external reference?

                 

                You are totally on the right track with the switchyard.xml snippet you posted.  The only thing you are missing is the binding on the composite reference.  Once that is in place, the error message about missing service will go away (the binding will register a service proxy on the bus).

                Btw, is there somewhere I can check out the "IRC discussion" you mention?

                 

                It's #switchyard on irc.freenode.org.  There is an archive available as well.  Here's an example:

                http://echelog.com/logs/browse/switchyard/1360105200

                1 of 1 people found this helpful
                • 5. Re: Camel route endpoint format for external SOAP binding
                  Paul Kristensen Newbie

                  A quick followup in case others end up down the same road I did - had some tinker-time today and tried it out:

                   

                  Changing the contents of the sca:reference node in switchyard.xml from:

                   

                  <sca:reference name="ServiceManagerExternalWebservice" multiplicity="0..1" promote="Route/ServiceManagerExternalWebservice">

                        <sca:interface.wsdl interface="TegFacadeChange.wsdl#wsdl.porttype(TegFacadeChangePortType)"/>

                  </sca:reference>

                   

                  ...removing the interface stanza and adding a binding instead (needs to point to a correct endpoint for the WSDL which is masked out in this example):

                   

                  <sca:reference name="ServiceManagerExternalWebservice" multiplicity="0..1" promote="Route/ServiceManagerExternalWebservice">

                         <soap:binding.soap>

                                  <soap:contextMapper/>

                                  <soap:wsdl>http://INSERT_VALID_ENDPOINT/SERVICE?wsdl</soap:wsdl>

                         </soap:binding.soap>

                  </sca:reference>

                   

                  Which did the trick - the error went away and the calls get routed from the REST binding through the Camel route and on to the external SOAP service - sweet.

                  Thanks for taking time to sort out the blue and red wires :-)

                   

                  /Paul