BT

Communication Flexibility Using Bindings

Posted by Anthony Elder, Raymond Feng, Simon Laws, Haleh Mahbod & Simon Nash on Jun 30, 2009 |

This article is adapted from a chapter from the book "Apache Tuscany in Action". It looks at how bindings are used to configure wire protocols for a component's service connections.

One of the most important features of SCA is its support for a wide variety of communication protocols. If your services need to talk Web Services, JMS, CORBA, RMI, or REST, they can do it using SCA and Tuscany. If they need to use some specialized or proprietary protocol to meet a particular application need, that's fine too. Even better, your business code doesn't need to know which protocol it's using; the choice of a protocol is made by (you guessed it) the component's configuration. How cool is that? The piece of SCA magic that makes all this possible is called a binding.

In this article, we'll see how to use bindings on services and references, and what it means if no bindings are configured. Finally we'll take a look at the SCA domain and see how bindings relate to communication within and outside an SCA domain.

Configuring Bindings for Services and References

You can use bindings on services or references. Putting a binding on a service means that the service can be invoked using the communication protocol specified by the binding. The service implementation code doesn't need to do anything special to make this happen; all you have to do is add the binding to the service's configuration.

For example, to make the Bookings service available as a web service, the component definition might look like this:

<component name="TripBooking">
  <implementation.java class="com.tuscanyscatours.TripBooking" />
  <service name="Bookings">
    <binding.ws uri="http://tuscanyscatours.com:8085/Bookings" />
  </service>
</component>

By adding the <binding.ws> element, we have told the SCA runtime that we want to expose the Bookings service as a web service using SOAP/HTTP at the endpoint specified in the uri attribute. That's all we need to do to create a web service. There's no need to learn JAX-WS or to make any changes to the Bookings service's implementation.

A service can have more than one binding. If we want to invoke the Bookings service over JMS as well as Web Services, we just need to add another binding. Here's an example component definition showing this:

<component name="TripBooking">
  <implementation.java class="com.tuscanyscatours.TripBooking" />
  <service name="Bookings">
    <binding.ws uri="http://tuscanyscatours.com:8085/Bookings" />
    <binding.jms />
  </service>
</component>

This makes the Bookings service also available over JMS using default configuration settings. Again it wasn't necessary to learn the JMS API or change any implementation code.

Bindings provide the linkage between SCA and Tuscany and the big wide world! The Bookings service is written in SCA and runs in Tuscany. Because this service is configured using bindings, it can be called by client code that isn't written using SCA or running in Tuscany. For web service calls to Bookings, the client code can be written in any language and can use any WS-I compliant Web Services runtime. For JMS calls, the client code can be written directly to the JMS API using any JMS provider that's compatible with the JMS provider configured for Tuscany's JMS binding.

We have seen how bindings can be used on SCA services to make them available using standard communication protocols. In the same way, bindings can be used on SCA references to call services using a standard communication protocol. In this case the roles are reversed; the client is implemented using SCA, and the service uses some standard communication protocol. For example, the service could be a web service endpoint that supports SOAP/HTTP, or it could be an EJB session bean communicating over RMI-IIOP. To talk to the Web service, the reference would use <binding.ws>; for calling the EJB, we need <binding.ejb>.

Figure 1 shows a diagrammatic representation of configuring bindings on a service and references of a component.

Figure 1: The Bookings service is configured with Web Services and JMS bindings, the "cars" reference is configured with a Web Services binding, and the "flights" reference is configured with an EJB binding.

An example component definition that configures the TripBooking component with the bindings pictured in figure 1 is shown in listing 1.

Listing 1 Configuring component services and references and services using wires

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	targetNamespace="http://tuscanyscatours.com/"
	name="bookings">
    <component name="TripBooking">
      <implementation.java class="com.tuscanyscatours.TripBooking" />
      <service name="Bookings">
	<binding.ws uri="http://tuscanyscatours.com:8085/Bookings" />
	<binding.jms />
      </service>
      <reference name="cars">
	<binding.ws uri="http://tuscanycars.com:8081/Cars" />
      </reference>
      <reference name="flights">
	<binding.ejb uri="corbaname:rir:#flight/FlightProviderHome" />
      </reference>
      <reference name="hotels" target="HotelProvider" />
    </component>
</composite>

You'll notice that the references in listing 1 that are configured with bindings don't have a target attribute. This is because the element provides the destination information for the reference, as well as specifying the communication protocol to be used.

We've looked at how bindings can be applied to services and references. In the next section we'll look at what happens for services and references that don't specify a binding in their configuration.

The Default Binding

In listing 1 we didn't specify a binding for the hotels reference. This means it has an implicit binding type of binding.sca (often called the default binding). The default binding is used to connect an SCA reference to an SCA service, leaving the choice of communication technology to the distributed SCA runtime into which the reference and service are deployed. Other bindings (such as binding.ws and binding.jms) select a specific communication protocol or API that can interoperate with non-SCA code. Because of this, bindings other than the default binding are often called interoperable bindings.

Tuscany uses Web Services over SOAP/HTTP for remote calls over the default binding; other SCA runtimes might use a different standard protocol such as RMI-IIOP, or they could use a proprietary protocol. In future Tuscany could switch to something else for the default binding, so Tuscany applications should not assume that using the default binding means they are getting Web Services. An application that wants to use Web Services to communicate between components should specify <binding.ws> to make sure this happens.

The default binding can only be used for connecting a reference to a service within the same SCA domain. Connections that span domain boundaries must specify an interoperable binding. The domain is an important concept in SCA, and we'll describe it in detail in chapter 4. In the next section we'll give a brief overview of what an SCA domain is and how it relates to bindings and wiring.

Domains, Bindings and Wiring

The SCA domain is a deployment and management boundary for SCA components. For example, a domain could be a single application server, a server cluster, or a group of servers or clusters. An entire domain typically runs a single vendor's implementation of SCA.

Every SCA component is part of an SCA domain. References and services within the same domain can be connected using wires. Connections between references and services within the same domain can use the default binding because SCA guarantees that the implementation of this binding will be consistent within a domain. For communication outside the domain, references and services can't use wires and instead use interoperable bindings to interact with other services.

We'll illustrate the use of domains with a scenario based on the TuscanySCATours company that we looked at in chapter 2. The company has grown and it has created a separate division to provide a specialized hotel booking service. This hotel booking service is used by the TuscanySCATours trip booking service and it is also available directly to customers who only want to book a hotel. The two divisions of the company use separate SCA domains to deploy and administer the services they provide: the TuscanySCATours domain for the original trip booking service, and the TuscanySCAHotels domain for the new hotel booking service. Figure 2 illustrates this scenario.

Figure 2 Two SCA domains containing components, showing how the components are connected, Wires (shown as solid lines) are used for connections inside each domain, and bindings (shown as broken lines with arrows) are used for connections that cross a domain boundary.

In figure 2 the solid lines connecting SCA components represent SCA wires, and the broken lines with arrows represent connections that use an interoperable binding instead of a wire. We'll start by looking at the connections from the references of the TripBooking component in the TuscanySCATours domain. Firstly, the flights reference is connected to a Web service that makes flight bookings. This isn't an SCA service, so the flights reference is configured with the interoperable binding <binding.ws> and the endpoint URI of the flight booking service.

Secondly, the hotels reference is connected to the Hotels service of the HotelProvider SCA component in the TuscanySCAHotels domain. Because SCA wires can't span domains, the reference and service are connected by configuring both of them with <binding.ws> and the service's endpoint URI. Finally, the cars reference of TripBooking is connected to the Cars service of the CarProvider component in the TuscanySCATours domain. Because the reference and service are in the same domain, we can connect them using an SCA wire and the default binding. The Cars service isn't exposed outside the TuscanySCATours domain and doesn't interoperate with non-SCA code, so there's no need for it to have any interoperable bindings.

Now let's look at the connections to the Hotels service of the HotelProvider component in the TuscanySCAHotels domain. As well as the connection from the hotels reference of the TripBooking component, there are connections from HotelBooker (a hotel booking client application that doesn't use SCA) and from the hotels reference of the SCA component HotelOffers in the TuscanySCAHotels domain. Because the Hotels service is configured using the interoperable binding <binding.ws>, the HotelBooker software can use any Web service client software to invoke the Hotels service. The connection between HotelOffers and HotelProvider uses an SCA wire because these components are in the same SCA domain. This wire could use either the default binding or the interoperable binding binding.ws that the service provides. In this example we have chosen to use binding.ws to illustrate that wires within an SCA domain don't always need to use the default binding.

It's useful to see how the connections in figure 2 would be configured in component definitions. Listing 2 shows the definitions for the components in the TuscanySCATours domain.

Listing 2 Component definitions for the TuscanySCATours domain

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	targetNamespace="http://tuscanyscatours.com/"
	name="toursdomain">
    <component name="TripBooking">
      <implementation.java class="com.tuscanyscatours.TripBooking" />
      <reference name="flights">
	<binding.ws uri="http://flightbookingservice.com:8084/Flights" />
      </reference>
      <reference name="hotels">
    <binding.ws uri="http://tuscanyscahotels.com:8083/Hotels" />
      </reference>
      <reference name="cars" target="CarProvider/Cars" />
    </component>
    <component name="CarProvider">
       <implementation.java class="com.tuscanyscatours.CarProvider" />
    </component>
</composite>

Listing 3 shows the component definitions for the TuscanySCAHotels domain:

Listing 3 Component definitions for the TuscanySCAHotels domain

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	targetNamespace="http://tuscanyscahotels.com/"
	name="hotelsdomain">
    <component name="HotelProvider">
      <implementation.java
	class="com.tuscanyscahotels.Hotels" />
      <service name="Hotels">
	<binding.ws uri="http://tuscanyscahotels.com:8083/Hotels" />
      </service>
    </component>
    <component name="HotelOffers">
      <implementation.java class="com.tuscanyscahotels.HotelOffers" />
    <reference name="hotels"
	target="HotelProvider/Hotels" >
	<binding.ws/> 1
      </reference>
    </component>
</composite>
1 the reference is configured to use binding.ws

It's important to specify on the hotels reference of HotelOffers. Without this, the reference would be configured to use binding.sca by default, and this would fail because the target service does not have binding.sca available in its configuration.

The example in figure 2 shows most of the ways that SCA references and services can be connected. It's also possible to use a matched pair of bindings to connect an SCA reference to an SCA service in the same SCA domain, as an alternative to wiring. A lot of the Tuscany samples do this (for example, the “helloworld” series) because this is an easy way to show how to configure matching bindings for the client and service ends of a connection.

We have described a number of options for how SCA references and services can be connected, and it's worth summarizing these briefly. To connect a reference and service in the same SCA domain, you can:

  • use a wire with the default binding
  • use a wire with an interoperable binding
  • configure the reference and service with matching bindings

To connect an SCA reference and SCA service that aren't in the same domain, you can:

  • configure the reference and service with matching interoperable bindings

To connect an SCA reference or service to non-SCA code, you can:

  • configure the reference or service with an interoperable binding

Interoperable bindings enable SCA code to interoperate with non-SCA code, and allow SCA code from different vendors to interoperate across a domain boundary. The default binding allows vendors to provide optimized communication where interoperability is not required.

For Source Code, Sample Chapters, the Author Forum and other resources, go to http://www.manning.com/laws.


This article is adapted from a chapter from the book "Apache Tuscany in Action". It looks at how bindings are used to configure wire protocols for a component's service connections.

InfoQ readers will receive a 25% discount when ordering via manning.com. Use discount code, "infoq25".

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread
Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT