1 2 Previous Next 24 Replies Latest reply on May 12, 2014 10:42 PM by kcbabo

    Tutorial on referencing a SOAP Web Service in another Composite

    steve.leach

      Hi all

       

      This really feels like a dumb question, but I've spent a couple of hours searching: is there a tutorial on importing and referencing services from one Switchyard composite to another?

       

      Cheers

      Steve

        • 1. Re: Tutorial on referencing a SOAP Web Service in another Composite
          jorgemoralespou_2

          Hi Steve,

          Can you be more specific on the question? Do you mean referencing from one composite the classes defined in another composite? If this is the case, you need to specify a dependency, either by jboss-deployment-descriptor or in MANIFESF.MF.

           

          In the multiApp quickstart you have an example. See maven-jar-plugin definition for order-consumer.

           

          Hope it helps.

          • 2. Re: Tutorial on referencing a SOAP Web Service in another Composite
            steve.leach

            Ahhh, thanks. MultiApp looks promising - I hadn't spotted the demos folder for some reason.

             

            I'll have a proper look tomorrow, but from an initial quick glance the pattern is to share Java classes, WSDLs etc. using Maven dependency management, yes?

             

            Out of interest, doesn't that lead to more tightly-coupled service consumers & providers than is desirable in a SOA/SCA environment?

            • 3. Re: Tutorial on referencing a SOAP Web Service in another Composite
              jorgemoralespou_2

              Steve Leach escribió:

               

              I'll have a proper look tomorrow, but from an initial quick glance the pattern is to share Java classes, WSDLs etc. using Maven dependency management, yes?

               

              Out of interest, doesn't that lead to more tightly-coupled service consumers & providers than is desirable in a SOA/SCA environment?

              As it is a dependency, you have to declare in you final artifact (service application, jar, war or ear) the dependency. Since it is a dependency in a provided by you artifact (what it is called dynamic module) you have to declare it in the MANIFEST.MF or with jboss-deployment file. Maven only helps you assemble the final artifact, but the dependency is managed at runtime in one of the specified ways.

               

              And yes, it leads to a more tightly-coupled, but there are not many other options, or?

              You will only share classes/wsdls if you need to define these in more than one composite application, and if they are calling from one to the other, they should be using SCA binding, so wsdl probably is not of use, but it is the classes (at least the Java interface defining these service), so in this case, an because of the dependency, maybe packaging everything together in an ear is a good option, so all of the dependencies goes though the same lifecycle and there are never unresolved dependencies if you undeploy the "interfaces" jar (module) while maintaining the services.

              1 of 1 people found this helpful
              • 4. Re: Tutorial on referencing a SOAP Web Service in another Composite
                kcbabo

                Ahhh, thanks. MultiApp looks promising - I hadn't spotted the demos folder for some reason.

                 

                The ear-deployment quickstart also demonstrates how multiple applications can be deployed with shared resources:

                quickstarts/ear-deployment at master · jboss-switchyard/quickstarts · GitHub

                 

                I'll have a proper look tomorrow, but from an initial quick glance the pattern is to share Java classes, WSDLs etc. using Maven dependency management, yes?

                 

                There are actually two considerations here:

                1) How shared resources are resolved at project development/build-time.  That would be handled via Maven.

                2) How shared resources are packaged when deployed to the runtime.  In general, the recommendation is to isolate shared resources and deploy them independently as a separate deployment (multiApp) or in the lib/ directory of an EAR.  Each approach has advantages/disadvantages.

                 

                Out of interest, doesn't that lead to more tightly-coupled service consumers & providers than is desirable in a SOA/SCA environment?

                 

                Can you elaborate a bit on this point?  If multiple applications share a dependency, we are recommending that the dependency is isolated in a distinct module and shared instead of including multiple copies of it in your applications.  Consumers and providers in SOA interact through contracts, so agreement on a shared contract is a necessary prerequisite.  Now, you have the freedom to choose whether that contract is Java, WSDL, or something else and the details of the contract (operation granularity, message types, etc.) can have a large impact on the level of coupling.

                • 5. Re: Tutorial on referencing a SOAP Web Service in another Composite
                  steve.leach

                  Keith Babo wrote:

                   

                  Out of interest, doesn't that lead to more tightly-coupled service consumers & providers than is desirable in a SOA/SCA environment?

                   

                  Can you elaborate a bit on this point?  If multiple applications share a dependency, we are recommending that the dependency is isolated in a distinct module and shared instead of including multiple copies of it in your applications.  Consumers and providers in SOA interact through contracts, so agreement on a shared contract is a necessary prerequisite.  Now, you have the freedom to choose whether that contract is Java, WSDL, or something else and the details of the contract (operation granularity, message types, etc.) can have a large impact on the level of coupling.

                   

                  Well, in SOA you generally want the interface between two services to be defined as much as possible by the service contract. For SOAP services that is a WSDL file published over HTTP. That should be all you need to consume the service. For example, with plain old JAX-WS you publish the service interface WSDL from one app (WAR/EAR), then import that WSDL (using an HTTP URL) into another project and it generates a client stub which you use in your code. You might have a slightly different mechanism for publishing/consuming the WSDL, but the model is essentially the same.

                   

                  In the MultiApp demo, however, the WSDL is published through a Maven dependency, which is fair enough I suppose, but so are the Java classes and interfaces. This feels like tighter-coupling than the JAX-WS model to me. One of the key drivers behind SOAP Web Services (and things like CORBA before that) was to get away from shipping code between projects when loose coupling is desirable.

                   

                  Even a directly shared WSDL isn't entirely without risks. In general you want to have the ability for service consumer and service provider to disagree slightly (and hopefully temporarily) on the service contract, using some sort of service mediation layer (ESB) to do the necessary conversions. I guess you could say that in this case SwitchYard itself is acting as the mediator, so maybe it doesn't matter.

                   

                  I'm not sure I understand the point about choosing whether contracts are Java or WSDL, etc. Haven't we always had this choice?

                  • 6. Re: Tutorial on referencing a SOAP Web Service in another Composite
                    kcbabo

                    Good discussion. :-)

                    Well, in SOA you generally want the interface between two services to be defined as much as possible by the service contract. For SOAP services that is a WSDL file published over HTTP. That should be all you need to consume the service. For example, with plain old JAX-WS you publish the service interface WSDL from one app (WAR/EAR), then import that WSDL (using an HTTP URL) into another project and it generates a client stub which you use in your code. You might have a slightly different mechanism for publishing/consuming the WSDL, but the model is essentially the same.

                     

                    Absolutely you want the interaction to be described completely by the contract.  I disagree that JAX-WS provides a level of decoupling at all since you need to compile the client against generated Java stubs.  In all scenarios, you are relying on the fact that the WSDL does not change incompatibly, which means both consumer and provider rely on an identical (I could bend this to equivalent for corner cases) WSDL definition.  Since we recognize that both applications require access to the contract, then it simply becomes a choice of how that contract is accessed at development and runtime.  If you are dealing with WSDL contracts, there's no harm in packaging multiple copies, but it's a brittle choice in the face of change (ditto for generated JAX-WS client stubs).  Having multiple copies of Java interfaces and data objects is a bad idea from a class loading perspective in addition to these concerns.

                     

                    In the MultiApp demo, however, the WSDL is published through a Maven dependency, which is fair enough I suppose, but so are the Java classes and interfaces. This feels like tighter-coupling than the JAX-WS model to me. One of the key drivers behind SOAP Web Services (and things like CORBA before that) was to get away from shipping code between projects when loose coupling is desirable.

                     

                    Java interfaces are a choice, not a requirement.  They provide a lot of convenience in certain scenarios.  You could use WSDL in the same app if you really wanted to use XML for all consumer-provider interactions across application boundaries.  I have been down the road where everyone is forced to use WSDL and it ends in tears and anguish. ;-)

                     

                    I'm not sure I understand the point about choosing whether contracts are Java or WSDL, etc. Haven't we always had this choice?

                    Yes, of course.  My point is that the type of contract itself, no matter how it's resolved by consumers/providers, has a great impact on coupling.  If I have a Java contract, for example, then I'm assuming Java data objects and Java clients.  If I use WSDL, then it's XML which opens up the service to non-Java clients.  To be extra clear on this point - using an @WebService with JAX-WS is not equivalent to a Java contract for a service.  WSDL is generated from that, which is the actual contract that consumers will see.  In SwitchYard, you can define a component-level (which is private to the application) contract of Java and then simply generate WSDL which is used for the composite (public) service consumed by external clients.

                    • 7. Re: Tutorial on referencing a SOAP Web Service in another Composite
                      steve.leach

                      Jorge Morales wrote:

                       

                      Hi Steve,

                      Can you be more specific on the question? Do you mean referencing from one composite the classes defined in another composite? If this is the case, you need to specify a dependency, either by jboss-deployment-descriptor or in MANIFESF.MF.

                       

                      In the multiApp quickstart you have an example. See maven-jar-plugin definition for order-consumer.

                       

                      Hope it helps.

                       

                      Thanks for the MultiApp example, Jorge. I've got it working now, and I think I understand how it all works.

                       

                      What I don't understand yet is how it was built. Was it created using the JBDS tooling, which is what I'm trying to use?

                       

                      I'm trying to re-create the OrderService reference in the order-consumer project. I think I'm supposed to create the component first, then add a reference, then promote that reference. I believe I need to use a WSDL interface type (out of interest, what is the "ESB" interface type?). I can then either create a new WSDL (not appropriate here) or browse for one, but the browse window doesn't show any WSDL files at all. I was hoping I could just type the HTTP URL to the WSDL (http://localhost:8080/quickstart-demo-multiapp/OrderService?wsdl) but there's no option to do that.

                       

                      What am I doing wrong? I suspect I'm missing something fairly fundamental.

                       

                       

                      @Keith, I'll reply to you separately (and maybe we should move that discussion into a separate thread anyway).

                      • 8. Re: Tutorial on referencing a SOAP Web Service in another Composite
                        jorgemoralespou_2

                        Hi Steve,

                        Since I haven't done the quickstarts I can not really answer, but I guess that it was built with JBDS as it is the easiest way.

                        The process can be very simple, but depends on how you want to expose your service.

                        If you want your service to be exposed in an SCA binding, then promoting the service interface as Java is the way to go.

                        On the other hand, if you want your service exposed with a SOAP binding, then you should promote your interface as wsdl, add the transformers (if needed) and that's it.

                         

                        There are very nice videos in vimeo from Keith (the master here): http://vimeo.com/search?q=switchyard+ep

                        And there is some labs with information on github: https://github.com/jboss-switchyard/learning

                         

                         

                        As to mention about the other discussion, SCA is not SOA. SCA applications can run in the same container, so artifacts can be shared as a dependency. Of course your services are coupled in some ways, even in SOA. Loosely coupling in SOA can be achieved by having a BUS in the middle that let service contracts evolve, but in this scenario, the ESB will be coupled with every service provider. Interfaces must match.

                         

                        In SCA, and SCA calls, because these services are called from within the same container, these interface definition can be shared (for reusability) but services are still coupled.

                         

                        In the scenario that you talk, where services are discovered, stubs dynamically generated, and so, there is one important drawback, which is "performance", so that's why most of the service (consumers/providers) provide the stubs for the calls, and these stubs are coupled to the interface, and thus, can be shared between services that use that interface.

                        • 9. Re: Tutorial on referencing a SOAP Web Service in another Composite
                          steve.leach

                          Thanks again Jorge.

                           

                          My problem isn't with promoting services, its with promoting (or otherwise creating) references. The right hand side of the SCA diagram. I'm pretty comfortable with promoting services, including Java to WSDL transformation, in SY now.

                           

                          The tutorials you've linked are all pretty good, but unless I'm missing something obvious, none of them show importing a SOAP service from one composite as a reference in another one. And the quickstarts that do this are already built, so I can't see how it was done.

                           

                          What I was hoping for is something like...

                          1. Create Project SY1, add a Java component with a Java interface (hello world or something)
                          2. Promote the Java component interface as a WSDL composite interface, with a SOAP binding
                          3. Create Project SY2
                          4. Import the WSDL from SY1 as a composite reference, with a Java interface
                          5. Create a Java component with a component reference to the composite reference from above
                          6. Test this new component

                           

                          The MultiApp quickstart has obviously gone through this process, but I can't figure out how they did step 4.

                           

                           

                          Regarding SOA/SCA and interfaces, I fully understand your point, and I'm in no way trying to say that all interfaces should be SOAP Web Services. However, with this example, MultiApp, the decision has been made to go with a SOAP Web Service interface, rather than any of the other options. I'd therefore expect loose coupling is more important than maximum performance for this specific interface, and hence was slightly confused about the sharing of Java classes between the service provider and the service consumer. After all, If you're going to share a classloading context anyway, why bother with SOAP at all?

                          • 10. Re: Tutorial on referencing a SOAP Web Service in another Composite
                            kcbabo

                            Every quickstart I create is done using SY tooling because:

                            (1) I want to test the tooling

                            (2) The tooling makes me more productive, which means I spend less time building the example

                             

                            Each contributor to the project has their own preferences though, so I can't say that every quickstart was created in JBDS.  I created the multiApp quickstart and I can confirm it was done using SY tooling.

                            • 11. Re: Tutorial on referencing a SOAP Web Service in another Composite
                              kcbabo

                               

                               

                              What I was hoping for is something like...

                              1. Create Project SY1, add a Java component with a Java interface (hello world or something)
                              2. Promote the Java component interface as a WSDL composite interface, with a SOAP binding
                              3. Create Project SY2
                              4. Import the WSDL from SY1 as a composite reference, with a Java interface
                              5. Create a Java component with a component reference to the composite reference from above
                              6. Test this new component

                               

                              The MultiApp quickstart has obviously gone through this process, but I can't figure out how they did step 4.

                               

                               

                              Two things with step 4 above:

                              1) Importing a WSDL from a URL is not supported right now, but it's a very desirable feature.  This means you'll have to save the WSDL locally and import it into your project by adding it directly to the project or resolving it via a dependency.

                              2) The composite reference contract would be WSDL, not Java.  The component reference, which belongs to the service logic which is invoking the service, can certainly be Java though.

                              • 12. Re: Tutorial on referencing a SOAP Web Service in another Composite
                                kcbabo

                                After all, If you're going to share a classloading context anyway, why bother with SOAP at all?

                                 

                                Because there can be many consumers of an application's services.  Some consumers could be deployed in separate applications, but produced by the same team with the knowledge that they will always be deployed in the same container.  That's a choice that's really up to the developers.  In the case of multiApp, both approaches are demonstrated - the applications talk to one another via binding.sca but also expose services to the outside world via binding.soap.

                                • 13. Re: Re: Tutorial on referencing a SOAP Web Service in another Composite
                                  jorgemoralespou_2

                                  Keith Babo escribió:

                                   

                                  1) Importing a WSDL from a URL is not supported right now, but it's a very desirable feature.

                                  Hi,

                                  As far as I know, the wsdl must be accessible for the configuration to be able to deploy the service to the binding as well as for the sca:interface, right now, but it would be nice if it could get it from thee S-RAMP repo via an S-RAMP query at deploy time.

                                   

                                  Cheers,

                                  • 14. Re: Tutorial on referencing a SOAP Web Service in another Composite
                                    steve.leach

                                    Keith Babo wrote:

                                     

                                    After all, If you're going to share a classloading context anyway, why bother with SOAP at all?

                                     

                                    Because there can be many consumers of an application's services.  Some consumers could be deployed in separate applications, but produced by the same team with the knowledge that they will always be deployed in the same container.  That's a choice that's really up to the developers.  In the case of multiApp, both approaches are demonstrated - the applications talk to one another via binding.sca but also expose services to the outside world via binding.soap.

                                    Except that in MultiApp the order consumer talks to the order service via binding.soap not binding.sca, which is what I was getting at. Using an SCA binding and sharing Java classes makes sense; its using a SOAP binding and sharing the classes that I can't quite get my head around.

                                     

                                    Anyway.... I created a new SY project and copied the order service WSDL + XSD into it. I was then able to create a Camel (Java) component, with a Java service interface and a WSDL reference (using the order service WSDL). I could then promote the reference and the service. What I haven't figured out how to do yet is consume the reference from a Java Bean component: from what I can see a Bean component can't have a reference with a WSDL interface.

                                     

                                    I know how to convert a Java interface to a WSDL one as part of the service promotion process, I just can't see how to convert from WSDL to Java in the reference promotion.

                                     

                                    @Jorge - using S-RAMP for interface definitions sounds perfect.

                                    1 2 Previous Next