12 Replies Latest reply on Apr 29, 2013 9:26 AM by mageshbk

    Http Binding question

    jcoders

      hi,

         I am trying to do the following

       

      1) pick up documents from a ftp folder, route it using camel to a reference end point that has http binding to post the file to a RESTeasy webservice

       

      Everything works fine all the way to the posting part, i have debug statements in the webservice firing off saying it got the document, printing etc works but i m not sure how to get/process the response i would get back from the RESTeasy webservice.My switchyard.xml is as follows

       

       

      <?xml version="1.0" encoding="UTF-8"?>
      <switchyard xmlns="urn:switchyard-config:switchyard:1.0" xmlns:camel="urn:switchyard-component-camel:config:1.0" xmlns:file="urn:switchyard-component-camel-file:config:1.0" xmlns:ftp="urn:switchyard-component-camel-ftp:config:1.0" xmlns:http="urn:switchyard-component-http:config:1.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="switchyard-myFtp" targetNamespace="urn:com.example.switchyard:switchyard-myFtp:1.0">
        <sca:composite name="switchyard-myFtp" targetNamespace="urn:com.example.switchyard:switchyard-myFtp:1.0">
          <sca:component name="CamelServiceRoute">
            <camel:implementation.camel>
              <camel:java class="com.example.switchyard.switchyard_myFtp.CamelServiceRoute"/>
            </camel:implementation.camel>
            <sca:service name="CamelService">
              <sca:interface.java interface="com.example.switchyard.switchyard_myFtp.CamelService"/>
            </sca:service>
            <sca:reference name="FileWriter">
              <sca:interface.java interface="com.example.switchyard.switchyard_myFtp.FileWriter"/>
            </sca:reference>
          </sca:component>
          <sca:service name="CamelService" promote="CamelServiceRoute/CamelService">
            <sca:interface.java interface="com.example.switchyard.switchyard_myFtp.CamelService"/>
            <ftp:binding.ftp>
              <operationSelector operationName="acceptMessage"/>
              <ftp:contextMapper/>
              <ftp:directory>in</ftp:directory>
              <ftp:host>host</ftp:host>
              <ftp:username>${userName}</ftp:username>
              <ftp:password>pwd</ftp:password>
              <ftp:consume>
                <ftp:delete>true</ftp:delete>
                <ftp:recursive>true</ftp:recursive>
              </ftp:consume>
            </ftp:binding.ftp>
          </sca:service>
          <sca:reference name="FileWriter" multiplicity="0..1" promote="CamelServiceRoute/FileWriter">
            <sca:interface.java interface="com.example.switchyard.switchyard_myFtp.FileWriter"/>
              <http:binding.http>
              <http:contextMapper/>
              <http:address>http://localhost:8080/IronMan3/service/order/int</http:address>
              <http:method>POST</http:method>
              <http:contentType>text/plain</http:contentType>
            </http:binding.http>
          </sca:reference>
        </sca:composite>
      </switchyard>

       

      my camel route is in java dsl and looks like the following

       

       

      package com.example.switchyard.switchyard_myFtp;
      import org.apache.camel.Exchange;
      import org.apache.camel.builder.RouteBuilder;
      
      public class CamelServiceRoute extends RouteBuilder {
       /**
        * The Camel route is configured via this method.  The from:
        * endpoint is required to be a SwitchYard service.
        */
       public void configure() {
        // TODO Auto-generated method stub
        from("switchyard://CamelService").log(
          "Received message for 'CamelService' : ${body}")
        .choice()
        .when(
          ///give full xpath below
          xpath("//a:A/a:B = 'blah'")
          .namespace("a", "http://someval")
          )
          .to("switchyard://FileWriter")
         // .process(new PrintResult())
        .otherwise()
          .to("file:D:/Temp/wd");    
          
       }
      }
      
      

       

      How i get the response back from the webservice in the CamelServiceRoute class above ? I tried the .process method but it prints out the entire original message versus the response.My PrintResult class is as follows

       

       

      package com.example.switchyard.switchyard_myFtp;
      import org.apache.camel.Exchange;
      import org.apache.camel.Processor;
      public class PrintResult implements Processor {
      public void process(Exchange exchange) throws Exception {
          String msg =  exchange.getIn().getBody(String.class);
             
             System.out.println("Data received: " + msg);
          }
      }
      
      

       

      Thanks in advance

        • 1. Re: Http Binding question
          splatch

          Your exampel is good. If you would like to use webservice then you need SwitchYard binding.soap reference. After calling Web Service from route you will have reply from this web service as actual message body:

           

          from("switchyard://myServiceImpl") // here you have payload your binding received
              .to("switchyard://ws") // call reference
              .log("My actual body is ${body}") // you should have here reply from WS
              .to("switchyard://anotherWs");
          

           

          Web service requires proper reference definition:

           

          <reference multiplicity="0..1" name="SomeReference" promote="SomeService/SomeReference">
              <soap:binding.soap xmlns:soap="urn:switchyard-component-soap:config:1.0">
                  <soap:wsdl>external-service-wsdl.wsdl</soap:wsdl>
                  <soap:endpointAddress>http://localhost:8090/someService</soap:endpointAddress>
              </soap:binding.soap>
          </reference>
          
          

           

          The problem with DSL is lack of some constructions, ie. you may need to transform data with custom Java code. If so - you don't have always use custom Processor which are general purpose. You may decide to use camel bean binding and it's annotations. They are really cool. Eg. you may do constructions like this:

           

          @Named("bts")
          class BeanTransformer {
              public Node getActualPayload(Node body, @Header("issue-id") String issueId) {
                  body.setAttribute("node-id", issueId);
                  return body;
              }
          }
          

           

          And reference it in camel route:

           

          from("...").beanRef("bts")
          

           

          Be aware that @Named is CDI annotation and requires presence of META-INF/beans.xml to work.

           

          More examples of bean binding you may find in camel documentation.

          • 2. Re: Http Binding question
            jcoders

            I am confused, the webservice i am calling is a RESTeasy webservice, do i still need to use "SwitchYard binding.soap reference" ??

            • 3. Re: Http Binding question
              splatch

              Sorry, for resteasy you just need binding.rest, binding.soap is for WSDL based deployment.

              • 4. Re: Http Binding question
                jcoders

                No worries , If i use the binding.rest for RESTeasy how do i process the response back ?, a sample code snippet would be awesome, a newbie here loving the opportunity to learn

                • 5. Re: Http Binding question
                  splatch

                  We have camel-soap-proxy quickstart which calls external SOAP web service. From SwitchYard point of view called enpoint can be also resteasy based service. The point is - anything you have in your route definition before calling switchyard refererence operates on input passed yo your service. After calling reference your exchange will have reply from rest easy service as payload.

                   

                  Steps to get it working - based on your code snippets:

                  • Add reference inside sca:component
                  • Create sca:reference with binding.rest
                  • In camel service implementation use new reference name inside to("switchyard://....") block

                   

                  You may take a look on camel sopa proxy switchyard.xml or switchyard.xml from rest quickstart which uses switchyard bean component to implement service.

                  • 6. Re: Http Binding question
                    jcoders

                    Thank you for the quick reply. i have the following questions and is still unclear on how to do this

                     

                    1) I tried adding the REST binding via the tool to the existing reference (removed the http binding on it), but and is stuck at the following screen

                    StuckWindow.bmp

                     

                    The webservice i have is not deployed in the same package as this switchyard example and is deployed seapartely, so i am not sure how the above will work if the webservices are not a part of the example package.My goal is to post to external webservice that not withing the same switch yard implementation package.

                     

                    The earlier step of doing a simple http post worked for me, but was not sure on how to get the response back in the camelservice route class ( as in a 200/400 status or a custom response sent back by the webservice kinda deal)

                    • 7. Re: Http Binding question
                      jcoders

                      Still stuck with this, i seem to get further with Http binding versus REST binding when talking to a RESTeasy service external to switchyard, any ideas /suggestions ?

                      • 8. Re: Http Binding question
                        splatch

                        For rest services you need define JAX-RS annotated interface with @GET/@POST/@Path annotations.

                        • 9. Re: Http Binding question
                          rcernich

                          Hey Rajat,

                           

                          The http-binding quickstart shows how to invoke an HTTP reference.  The rules-camel-cbr quickstart shows how to invoke a reference and use its responce within a camel route.  Hopefully, the two of those together will help get you over the hump.  Sorry I don't have more.

                           

                          Best,

                          Rob

                          • 10. Re: Http Binding question
                            mageshbk

                            Hi Rajat,

                             

                            Have you looked at the rest-binding quickstart? That has a fair example of invoking external REST endpoints. You, of course have to create an interface that matches the rest service.

                             

                            Coming to the issue in hand, for manipulating the response received after the Camel route has been processed, you will have to define a filter or transform option. See Scripting Language section here:

                             

                            https://docs.jboss.org/author/display/SWITCHYARD/Camel

                             

                            If you do not want to use such scripts, then you can create a bean service that references the Camel route service and do the manipulation there.

                             

                            regards,

                            Magesh

                            • 11. Re: Http Binding question
                              jcoders

                              Thanks guys for the quick replies, much appreciated

                               

                              @Rob - I looked at the http - binding quickstart and thats where i picked up pointers on how to with the http stuff>havent looked at the rules-cbr-quickstart so will get to that today

                               

                              @ Magesh

                               

                              I had looked at the rest-binding-quickstart and noticed that the interface and the webservice actually exist within the same sample/package.So if i am callling a external webservice but have the interface/contract for that external webservice in my build but no actual classes how will it resolve it and go to the right webservice ? based on the url i provide in the binding ? Sorry for the 20 questions , i started working/exploring Switchyard last week as this came up as a possible route we would take here at work, and have been excited at the opportunity to learn.

                              • 12. Re: Http Binding question
                                mageshbk

                                Rajat,

                                So if i am callling a external webservice but have the interface/contract for that external webservice in my build but no actual classes how will it resolve it and go to the right webservice ? based on the url i provide in the binding ?

                                Now, you are again confusing between Webservices(JAX-WS/JAX-RPC) and JAX-RS services. Like the old WebService contract called WSDL, which was provided for you when you set an endpoint address, JAX-RS endpoints do not provide one by default. In both the cases you will need a contract. For Webservices it is the WSDL and for JAX-RS (RESTEasy etc.,) it is the JAX-RS annotated interface ATM. We do not yet have support for WADL though. We might add it in the future.

                                Sorry for the 20 questions , i started working/exploring Switchyard last week as this came up as a possible route we would take here at work, and have been excited at the opportunity to learn.

                                You are most welcome to ping us with any level of questions that you may have. Happy exploring and please do not forget to give your feedback!

                                 

                                thanks,

                                Magesh