2 Replies Latest reply on Oct 6, 2016 8:21 PM by ggmcgibbon

    Using JBDS to generate a REST front end that drives a remote SOAP

    hpuri

      For a final implementation in Fabric8, I need to create a local REST front end that drives a remote SOAP endpoint

      Example remote service - I am using http://www.webservicex.net/airport.asmx?wsdl with the operation getAirportInformationByAirportCode  which takes a string airport code e.g. "TPA" or "ORD" and returns a string XML fragment .

      Using the service only because it is simple, works, and has no security. I will layer in digital signatures later.

       

      Looking at the standard Fuse examples I got thoroughly confused between blueprint.xml, spring and CXF. I am hoping to create a sequence of steps for JBDS that will allow less technical users to create the proxy.

      I started with Red Hat JBoss Developer Studio Version: 10.1.0.GA Build id: GA-v20160902-1725-B43 Build date: 20160902-1725

      I don't know if that one is buggy (please advise if I should switch to a lower version e.g. 9 or 8)

       

      I created a new Fuse project with archetype camel-archetype-cxf-contract-first-blueprint

      removed the code and wsdl and placed the new wsdl, and updated the pom.xml

      observed the web service code generated in the package name derived from the wsdl = net.webservicex.*

      I wrote a small test program that spits out the return to test the generated code works.

      public static void main(String[] args) {
         Airport aa = new Airport(); //SEI
         AirportSoap as= aa.getAirportSoap12(); //port
         String resp =as.getAirportInformationByAirportCode("TPA");
         System.out.println(resp);

          }

       

      this works and returns

      <NewDataSet>

        <Table>

          <AirportCode>TPA</AirportCode>

          <CityOrAirportName>TAMPA TAMPA</CityOrAirportName>

          <Country>United States</Country>

          <CountryAbbrviation>US</CountryAbbrviation>

          <CountryCode>33</CountryCode>

      ::::::::::::::::::::::::::::::::::::::

       

      Now back to the blueprint. Seems like they got rid of the CXF endpoints in the palette for the design view so I added it in by hand but I am unsure how to set this up as a route. Looking at the example in  Fuse ESB Enterprise - Web Services and Routing with Camel CXF - Instantiate the WS Client Proxy i sought to use the same timer based client invoker as a first step but this did not work

       

      <?xml version="1.0" encoding="UTF-8"?>

      <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"

          xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"

          xmlns:jaxws="http://cxf.apache.org/jaxws"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd                   http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd                  http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd                  http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">

          <jaxws:client address="http://www.webservicex.net/airport.asmx"

              id="airportServiceProxy" serviceClass="net.webserviceex.Airport"/>

          <bean class="com.avalon.cdm.fuse.mlb.ClientInvoker"

              destroy-method="destroy" id="airportServiceClient" init-method="init">

              <property name="airportService" ref="airportServiceProxy"/>

          </bean>

          <cxf:cxfEndpoint address="/airport/" id="WSfront"

              serviceClass="net.webservicex.Airport" wsdlURL="wsdl/airport.wsdl"/>

          <cxf:cxfEndpoint address="/airport/" id="WSreal"

              serviceClass="net.webservicex.Airport" wsdlURL="wsdl/airport.wsdl"/>

          <camelContext id="camelContext-a02f90ab-413d-4513-8ccf-13ada3de22fb" xmlns="http://camel.apache.org/schema/blueprint">

              <route id="_route1">

                  <from id="WS" uri="cxf:beanId:WSfront"/>

                  <log id="_log1" message="Message received = ${body}"/>

                  <to id="WSreal" uri="cxf:beanId:airportServiceProxy"/>

              </route>

          </camelContext>

      </blueprint>

       

       

      Any examples, clues or advice on alternate approaches greatly appreciated ,

      Thanks

        • 1. Re: Using JBDS to generate a REST front end that drives a remote SOAP
          hpuri

          The specific web service at  http://www.webservicex.net/airport.asmx?wsdl supports many operations and protocols. You have to add enough details to the end point definition so the reference is unambiguous. Then it works.

          Since I struggled with it for long I am pasting the blueprint here in the hope it will help someone.

           

          <?xml version="1.0" encoding="UTF-8"?>

          <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"

              xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"

              xmlns:cxf="http://cxf.apache.org/blueprint/core"

              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd                   http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd                   http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd                   http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">

              <bean class="com.harry.airport.BeanAdapter" id="beanAdapter"/>

              <!-- this segment puts out nice formatted dump of the input and output SOAP payload -->

              <cxf:bus>

                  <cxf:features>

                      <cxf:logging/>

                  </cxf:features>

              </cxf:bus>

              <!-- FACADE web service -->

              <camelcxf:cxfEndpoint address="http://localhost:9080/airport/"

                  id="input-cxf" serviceClass="com.harry.airport.AirportCXF"/>

              <!-- TARGET WEB SERVICE -->

              <!-- This one is very tricky because it supports REST SOAP and SOAP12, and many operations so it is excellent for education.

              if you are confused look at the other project "Incident" which uses a web service with a single operation. It keeps things very simple

              Note that the service class is AirportSoap and not Airport nor AirportSoap12

              Also note the use of serviceName, endpointName AND defaultOperation to narrow down the field and point to a specific operation on a port on a service

              AARRRRRRRRRRGGGGGGGGGGGGGGGGHHHHHHHHHH!!! this was tough -->

              <camelcxf:cxfEndpoint

                  address="http://www.webservicex.net/airport.asmx"

                  endpointName="tns:airportSoap" id="SimpleWebSevice"

                  serviceClass="net.webservicex.AirportSoap"

                  serviceName="tns:airport" wsdlURL="wsdl/airport.wsdl" xmlns:tns="http://www.webserviceX.NET">

                  <camelcxf:properties>

                      <entry key="dataFormat" value="POJO"/>

                      <entry key="defaultOperationName" value="getAirportInformationByAirportCode"/>

                  </camelcxf:properties>

              </camelcxf:cxfEndpoint>

              <!--

              NOW we define the routes

              -->

              <camelContext id="example-cxf" xmlns="http://camel.apache.org/schema/blueprint">

                  <route id="input-cxf">

                      <from id="_from1" uri="cxf:bean:input-cxf"/>

                      <log id="_log2" message="Airport Code incoming = ${body} is null ${in.body} also null ${body[0]} gives class. Accessing field ${body[0].airportCode} using method ${in.body[0].getAirportCode} at ${date:now:yyyyMMdd}"/>

                      <transform id="_transform1">

                          <simple>${in.body[0]}</simple>

                      </transform>

                      <log id="_log1" message="Transformed Airport Code = ${in.body.airportCode}"/>

                      <transform id="_transform2">

                          <method bean="beanAdapter" method="transform"/>

                      </transform>

                      <removeHeaders id="_removeHeaders1" pattern="*"/>

                      <to id="_to1" uri="cxf:bean:SimpleWebSevice"/>

                      <!-- BTW you can also add on properties to the uri like this uri="cxf:bean:SimpleWebSevice?defaultOperationName=gaga"

                      but I like less cryptic ways of doing it like above -->

                  </route>

              </camelContext>

          </blueprint>

          1 of 1 people found this helpful
          • 2. Re: Using JBDS to generate a REST front end that drives a remote SOAP
            ggmcgibbon

            Thanks for posting this solution as this also stumped me when I tried using a version of the blueprint xml to call an internal SOA service.

             

            A question I have is how do you get code to generate by importing a uri. I'm using JBDS 8.1.0.GA or do you recommend using 10?

             

            Thanks,

             

            Gavin