5 Replies Latest reply on Jan 7, 2014 5:47 AM by phk

    Getting to a reference from a bean service




      I have this old SOAP based legacy webservice that I need to expose to clients as a REST service.

      So... Switchyard to the rescue!


      I have created a small SY application that consists of the following (in the end aiming at providing a bridge between REST and SOAP):


      • A reference to an external webservice (non-SY) with a WSDL interface and a SOAP binding on top
      • A bean-based service with a java interface
      • Promoted the bean service and added a REST binding to it (pointing to an interface definition that has REST annotations)


      In pursuing this I have yet to figure out the following pieces of the puzzle:

      How do I call the SOAP service from the bean service - somehow the bean service needs to get at the SOAP reference?


      Should I:

      a) Generate a java interface from the WSDL

      b) Use some other piece of kit from the SY toolbox?


      The examples use the camel based approach (the camel-soap-proxy) so they don't really point to an answer.

      I am still getting my feet wet on the SY terminology so any help is appreciated.




        • 1. Re: Getting to a reference from a bean service

          The way you invoke other services (whether local or remote) from a bean service is through a reference.  In fact, this holds true for any implementation type (Camel, BPEL, Java, BPM, Rules).  That's actually a nice thing about the application model in that all dependencies/invocations are represented using the same abstract concept - a reference.  What's different with each implementation is how the reference is represented in the implementation domain.  For Camel, a reference is mapped to a "switchyard://" endpoint which is invoked from a route.  For CDI Beans, a reference is injected into a service like so:


          @Inject @Reference
          private InventoryService inventory;


          The great thing about that reference is it's really just a proxy.  The provider behind the proxy can be another service local to the implementation (a Camel route or another bean, for example), or it can be an external service.


          In your scenario, what you want to do is:

          1) Add a reference to your bean service.

          2) Promote the reference to become a composite reference (this means the service provider is outside of the application) with a WSDL interface.

          3) Add a SOAP binding to the composite reference.

          4) Add a transformer which converts between the object type used in (1) and the XML format used in (2).


          You mentioned the SOAP service already exists, so you would likely get the WSDL you use for steps 2 and 3 from that existing service.


          As you come up to speed on SwitchYard, you might find the following training materials useful:

          learning/summit2013 at master · jboss-switchyard/learning · GitHub

          • 2. Re: Getting to a reference from a bean service

            Hi Keith,


            Thanks for taking time to breakdown things.


            What I did to generate my reference to the external webservice was:

            I dragged a "Reference" from the palette onto the canvas and chose WSDL as the interface type pointing it to the existing WSDL file and accepting the defaults suggested by the wizard.

            This created a reference node in the switchyard.xml as expected.


            So how do I go about promoting my reference (I can see the xml validation complains about a missing "promote" attribute on the sca:reference node and the tooling adds a warning sign about the newly created reference being unused).

            I added the @Inject @Reference annotations to my bean service - but I fell short as to what name to give it to resolve (like InventoryService in your snippet) which leads me to suspect that my reference hasn't been promoted


            Things I did try to workaround this:

            • Right-clicking the reference - but this gives no option to promote anything.
            • The context menu selection for the bean service "Create component reference" gives no option for a WSDL based interface (option greyed out)




            • 3. Re: Getting to a reference from a bean service

              Can you attach your project as it stands now?  That way I can provide you specific instructions using correct reference names.  Speaking in generic terms, if you already have a component reference (little purple nub on the component) and a composite reference (big purple nub on the composite), then you need to access the button bar on the component reference (hover over component reference and it will appear) and select the "<->" icon which allows you to wire a component reference to a composite reference.  This will associate/promote the component reference with the composite reference.


              It sounds like you have the bean implementation with the @Inject @Reference in place, but you haven't actually defined the reference in the switchyard metadata.  Use the button bar on the component to create the reference and specify a Java interface for the service interface.  The type of Java interface you use is the same as whatever the type is that you are injecting with @Inject @Reference. 

              • 4. Re: Re: Getting to a reference from a bean service



                I have created and attached a minimal project that takes me to the same point as my original project:


                To refresh - the concept was to expose an existing non-SY service (SOAP based) via REST using SY.

                I will try and give you an idea of what my intentions were and the actions taken via the tooling.

                I created a service "SimpleService" implemented as a bean and promoted this to become available from outside and added a REST binding on top as means of communication.

                The RESTful interface is defined by the "SimpleResource" interface in the project.


                In my attached project the external service is represented by the "ReversalService". I added a reference with the WSDL from the external service as interface description.

                I am able to invoke my REST service and get the call routed to the bean service - now I'd like for the bean service to call the external service.

                This would eventually be accomplished by injecting it via @Inject @Reference into the "SimpleServiceBean" side of things.


                From what I've understood from your previous answers I seem to be missing a component reference on the "SimpleServiceBean" - since I have no purple nub on it.


                Thanks for your patience,


                • 5. Re: Re: Re: Getting to a reference from a bean service

                  Ahhh... made some progress...

                  In my pursuit of the purple nub I hovered over the "SimpleServiceBean" and selected the "Create component reference" option.

                  When prompted for an interface I opted to create a simple new one:


                  package com.example.switchyard.soap_consumer_example;
                  public interface ExternalService {
                      String reverse(String stringToReverse);


                  (Types kept non-complex for the sake of sanity in this example)

                  The nub appeared and after choosing the "Wire" option (also selectable when hovering) and dragging it to the "ExternalService" reference the following result was created:




                  Now it's a matter of injecting the reference into the bean and creating the transformers (will post here when that's done).