SCA revisited: Helios and Eclipse SCA tools

Red wine in Tuscany 2.0

This article revisits the world of Eclipse SCA using Eclipse Helios and the latest plug-ins from the SCA Tools project, with a focus on getting up and running with Tuscany 2.0—a subject with little documentation available anywhere. Learn how to start using the most current tools for building SCA applications.

Ken McNeill (ken@mc-neill.net), Software Consultant, IBM

Ken McNeill is a consulting Engineer and open source activist involved with Java-based MDA and SOA-driven software. He consults regularly for IBM in Nice, France.



05 October 2010

Also available in Russian Japanese

The Eclipse Service Component Architecture (SCA) is one of the pillars supporting the SOA strategies of companies like IBM and Oracle. In its simplest form, SCA is all about modeling distributed composite applications using components and wires. SCA has been called "a good way to do SOA" for several reasons, many of them related to the aspect-oriented programming notion of separation of concerns.

For example, SCA decouples individual service components from the overall application orchestration (called an assembly in SCA). This means that you can model an application as a collection of components and assemble it later at deployment time (and subsequently reassemble it as needed). In addition, SCA explicitly decouples network protocols such as HTTP and IIOP from component implementations, leaving you free to focus on the business of code. Moreover, SCA has facilities for working with such things as dependency injection, policies, and run time configuration properties.

The SCA specifications were first published in November 2005 by the Open Service Oriented Architecture (OSOA; see Resources for links to more information), with the official version 1.0 coming to light in 2007. SCA specifications were then transferred to the Organization for the Advancement of Structured Information Standards (OASIS) group, where version 1.1 is still in draft form and the latest revision is dated January 2010. SCA version 1.1 is largely compatible with its predecessor, and many of the changes concern semantic clarifications as to how SCA run times should handle certain constructs in the SCA composite file.

The beauty and power of SCA come primarily from the ability to visually model and configure a composite application. Mature Eclipse technologies such as Eclipse Modeling Framework and Graphical Modeling Framework come together in SCA Tools for the purpose of building SCA applications. In addition, SCA Tools has drag-and-drop support for SCA run time extensions defined and implemented in Apache Tuscany and other environments.

Tuscany implements the SCA run time specifications—versions 1.0 and 1.1—in the project's two release branches, 1.x, and 2.x, respectively. Historically, Tuscany has been the reference SCA implementation, although other run times exist, such as Fabric3 and FraSCati. Each Tuscany release is available for download in an archive containing around 160 JARs. However, most of the core SCA functionality is contained in just six JARs; the other 154 are for specific protocols, bindings, and extensions.

The SCA Tools setup environment

In this article, you use the latest Helios release of Eclipse (version 3.6), combined with the latest SCA Tools (version 2.1.0). To install the SCA Tools, open Eclipse, and then perform these steps:

  1. Click Help > Install New Software.

    The update site used is the standard Helios URL (http://download.eclipse.org/releases/helios).

  2. Click the plus sign (+) next to SOA Development, and then select the check box beside SOA Tools Feature, as shown in Figure 1.
    Figure 1. SOA Tools feature
    Screen shot of the Install screen, with selections described above

Note: You may be wondering why you don't install such features as Tuscany 1.x support. For this article, you won't use Tuscany SCA extensions.

Installing Tuscany 1.6 and 2.0

When you have restarted Eclipse, download Tuscany version 1.6 or later (see Resources) in one big .zip file. Do the same for Tuscany version 2.0 by downloading the 2.x archive. Extract both archives to separate locations for use later.


The composite

An SCA composite is an application comprising an aggregation of finer-grained components. A composite is also an XML file defining how the components are assembled and how they interact.

Create an SCA project by clicking New > Other... SCA > SCA Java Project in Eclipse. Doing so adds an Eclipse SCA Tools support library to the project's Referenced Libraries CLASSPATH container. This library is used primarily to annotate Java™ files. After that, you can either download and copy all files from the links provided in Resources or copy and paste all elements (the SCA composite file, the composite_diagram file, and the Java files) to the new project's source directory.

Note: If you choose to copy or create your own composite XML file, you can use the context menu after selecting it to generate the composite diagram from the composite.

Once copied or created, open the composite diagram file by clicking it.

Components

This article presents the simplest of scenarios—one in which a request is made to a service in order to get a review of a wine (after all, we are covering Tuscany). Because this article does not cover the distributed aspect of SCA, the example consists of three components that are completely local—all of which are implemented in Java code.

Looking at Figure 2, the WineReviewComponent is the primary "promoted" service, callable from an SCA client context. It acts as a dispatcher for components WhiteWineComponent and RedWineComponent, depending on the type of wine in the original request. WhiteWineComponent and RedWineComponent return a hard-coded, "canned" description of a white or red wine, respectively. The WineReviewComponent formats the description and returns the response.

Figure 2. Composite diagram
A diagram showing the Wine review component and the White wine component and Red wine component, with arrows pointing from the first to the latter.

Listing 1 shows the SCA composite file that this diagram represents.

Listing 1. WineReview composite
<?xml version="1.0" encoding="UTF-8"?>
<csa:composite xmlns:csa="http://www.osoa.org/xmlns/sca/1.0" autowire="false"
name="WineReview" targetNamespace="http://example.org/winereview">
  <csa:component name="WineReviewComponent">
    <csa:implementation.java class="WineReviewImpl"/>
    <csa:service name="WineReviewService">
      <csa:interface.java interface="WineReviewService"/>
    </csa:service>
    <csa:reference multiplicity="1..1" name="ReferenceToWhiteWineData">
      <csa:interface.java interface="WhiteWineDataService"/>
    </csa:reference>
    <csa:reference multiplicity="1..1" name="ReferenceToRedWineData">
      <csa:interface.java interface="RedWineDataService"/>
    </csa:reference>
  </csa:component>
  <csa:service name="WineReviewService" promote="WineReviewComponent/WineReviewService"/>
  <csa:component name="RedWineComponent">
    <csa:implementation.java class="RedWineDataImpl"/>
    <csa:service name="RedWineDataService">
      <csa:interface.java interface="RedWineDataService"/>
    </csa:service>
  </csa:component>
  <csa:component name="WhiteWineComponent">
    <csa:implementation.java class="WhiteWineDataImpl"/>
    <csa:service name="WhiteWineDataService">
      <csa:interface.java interface="WhiteWineDataService"/>
    </csa:service>
  </csa:component>
  <csa:wire source="WineReviewComponent/ReferenceToWhiteWineData"
target="WhiteWineComponent/WhiteWineDataService"/>
  <csa:wire source="WineReviewComponent/ReferenceToRedWineData"
target="RedWineComponent/RedWineDataService"/>
</csa:composite>

The composite describes the three components, their interfaces, and their implementations. Notice that the namespace declaration, xmlns:csa="http://www.osoa.org/xmlns/sca/1.0", is an SCA version 1.0 file, intended to be implemented and run in a 1.0 environment.

Services

Because this SCA example is entirely Java based, all services are Java interfaces. At the top level, clients use the WineReviewService interface to request wine reviews according to the type of wine. (In this example, only WHITE and RED are used; in a more realistic scenario, you imagine that the "dispatch" would occur by appellation—for example, chianti, barbaresco—and vintage.)

Listing 2 shows the WineReviewService.

Listing 2. WineReviewService
public interface WineReviewService {

	public enum WINE_TYPE {
		WHITE, RED;
	}

	public String getWineReview(WINE_TYPE type);
}

The WineDataService is meant to be implemented by providers of specialized wine data services and is extended by two other interfaces—one for WHITE and one for RED. Listing 3 shows this service.

Listing 3. WineDataService
public interface WineDataService {

	public String getWineReviewData();
}

public interface WhiteWineDataService extends WineDataService {
}

public interface RedWineDataService extends WineDataService {
}

Implementations and annotations

Now, let's look at the dispatcher implementation, WineReviewImpl.java. This dispatcher is provided in Listing 4.

Listing 4. WineReviewImpl
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Service;

@Service(value = WineReviewService.class)
public class WineReviewImpl implements WineReviewService {

	@Reference(name = "ReferenceToWhiteWineData", required = true)
	protected WineDataService refToWhiteWineService;

	@Reference(name = "ReferenceToRedWineData", required = true)
	protected WineDataService refToRedWineService;

	public String getWineReview(WINE_TYPE type) {

		String description = null;

		switch (type) {

		case WHITE:
			description = refToWhiteWineService.getWineReviewData();
			break;
		case RED:
			description = refToRedWineService.getWineReviewData();
			break;
		default:
			throw new IllegalArgumentException();
		}
		return "This " + type.toString() + " wine is " + description;
	}
}

The first annotation tells the SCA run time that this class is a service implementation of the Java interface WineReviewService.class. The two @Reference annotations tell the SCA run time that the declared fields—one for white wine, one for red wine—are required references to other components in the composite. These references will be automatically injected (initialized) by the run time, according to the wiring shown in the diagram in Figure 2. The caller of the service uses the getWineReview() method, specifying either white or red by way of an enumeration in the WineReviewService interface.

Listing 5 shows the two classes supplying the wine review data.

Listing 5. WhiteWineDataService
import org.osoa.sca.annotations.Service;

@Service(value = WhiteWineDataService.class)
public class WhiteWineDataImpl implements WhiteWineDataService {

	public String getWineReviewData() {
		return "crisp, with notes of citrus and honey";
	}

}

The terse class WhiteWineDataService in Listing 5 is an implementation of the service interface WineDataService in Listing 3. This fact is made explicit for the SCA run time by the @Service annotation above the class declaration. As you can see, WhiteWineDataService returns a hard-coded, generic description of a white wine. Again, a real-world implementation would likely query a database or search engine to find relevant information.

Now, let's move on to red wine. The RedWineDataService is shown in Listing 6.

Listing 6. RedWineDataService
import org.osoa.sca.annotations.Service;

@Service(value = RedWineDataService.class)
public class RedWineDataImpl implements RedWineDataService {

	public String getWineReviewData() {
		return "full-bodied, evoking black currants and tobacco";
	}

}

Listing 6 is simply a red-wine version of Listing 5, the only difference being in the text returned by the getWineReviewData() method. In an SCA composite application, you can think of components as the highest level of abstraction, followed by service interfaces—themselves implemented and subsequently mapped to the components.


Testing the composite

At this time, you have a composite file and the necessary Java classes ready to deploy to an SCA 1.0 environment. You now need to set up Tuscany 1.6.

Tuscany 1.6

For this example, you set up a minimalist Tuscany 1.6 environment to test the SCA application. Right-click the SCA project, and then click Build Path > Configure Build Path. Next, click Add Library, choose User Library from the list, and then click Next, as shown in Figure 3.

Figure 3. The user library
A screen shot of the Add library screen. User library is selected.

Now, click User Libraries > New, and provide a name: For this example, use Tuscany16. When you're done, click Add JARs to browse to the directory containing the Tuscany 1.6 archive. In the lib subdirectory, select the following required JARs:

  • tuscany-sca-all-1.6.jar
  • neethi-2.0.4.jar
  • jsr250-api-1.0.jar
  • javacc-3.2.jar
  • cglib-nodep-2.2.jar
  • geronimo-j2ee-jacc_1.0_spec-1.1.jar

When you are finished, the user library (with the JARs listed above) should appear in the project's build path. Now, you're ready to create some test code. Although SCA Tools comes with a test launcher facility, you'll be testing your example manually using your own Java main method. Doing so helps you understand what is going on "under the hood."

Listing 7 shows how to initialize a Tuscany 1.x environment, giving it the composite file to load, and then invoking your service method, getWineReview().

Listing 7. SCATesterT1
import org.apache.tuscany.sca.host.embedded.SCADomain;

public class SCATesterT1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		SCATesterT1 scaTester = new SCATesterT1();
		scaTester.testTuscany1();
	}

	void testTuscany1() {
		
		SCADomain scaDomain = SCADomain.newInstance("WineReview.composite");
		WineReviewService someService = scaDomain.getService(
				WineReviewService.class,
				"WineReviewComponent/WineReviewService");

		String result = someService
				.getWineReview(WineReviewService.WINE_TYPE.WHITE);
		System.out.println(result);

		scaDomain.close();
	}

}

To run this code, create or import the Java code. Right-click it, and then click Run As > Java Application. If all goes well, you will see the following text in the Eclipse console:

This WHITE wine is crisp, with notes of citrus and honey

Let's save the red wine test for Tuscany 2.0, so to speak.

Note: Using the very limited set of Tuscany JARs recommended in this article, you will see two logged warnings pertaining to the initialization of two Tuscany modules: jetty and databinding. This is normal, as those functionalities are not used in this example. Adding the necessary JARs to the user library prevents those warnings.

Tuscany 2.0

Now, you need to make some minor adjustments to certain resources to execute code in Tuscany's SCA 1.1 environment. First, change the namespace at the beginning of the WineReview.composite file, manually replacing:

xmlns:csa="http://www.osoa.org/xmlns/sca/1.0"

with:

xmlns:csa="http://docs.oasis-open.org/ns/opencsa/sca/200912"

Note: Because of current limitations in the SCA Tools, the composite XML file will be flagged in red as unvalidated, and you will no longer be able to open the associated diagram editor. This is a known issue; I hope the next version of the SCA Tools plug-in will remedy the situation.

Now, set up the Tuscany 2.0 libraries. Using the steps in the Tuscany 1.6 section, create a new user library called Tuscany20, and then select the following required JARs:

  • tuscany-sca-api-2.0-M5.jar
  • tuscany-base-2.0-M5.jar
  • cglib-2.2.jar
  • hazelcast-1.8.3.jar
  • hazelcast-client-1.8.3.jar
  • XmlSchema-1.4.3.jar

In this example, the SCA annotations for version 1.1 are semantically identical to version 1.0. However, the 1.1 annotation declarations are contained in different Java packages (Tuscany 2.0), and you must add them to the code. First, add the SCA 1.1 annotations to the WineReviewImpl class, as shown in Listing 8.

Listing 8. WineReviewImpl, v2
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Service;

@Service(value = WineReviewService.class)
@org.oasisopen.sca.annotation.Service(value = { WineReviewService.class })
public class WineReviewImpl implements WineReviewService {

@Reference(name = "ReferenceToWhiteWineData", required = true)
@org.oasisopen.sca.annotation.Reference(name="ReferenceToWhiteWineData", required=true)
protected WineDataService refToWhiteWineService;

@Reference(name = "ReferenceToRedWineData", required = true)
@org.oasisopen.sca.annotation.Reference(name="ReferenceToRedWineData", required=true)
protected WineDataService refToRedWineService;
...

Notice that the SCA 1.1 annotations (oasisopen) take a fully qualified package name. This is because the SCA 1.0 annotations (osoa) are already imported and present in the code. Next, do the same with WhiteWineDataImpl and RedWineDataImpl, as shown in Listing 9.

Listing 9. WhiteWineDataService, v2
import org.osoa.sca.annotations.Service;

@Service(value = WhiteWineDataService.class)
@org.oasisopen.sca.annotation.Service(value = { WhiteWineDataService.class })
public class WhiteWineDataImpl implements WhiteWineDataService {
...

There are now two @Service annotations in the implementation, each of which will only be taken into account in its own run time environment. Now, do the same for red wine (Listing 10).

Listing 10. RedWineDataService, v2
import org.osoa.sca.annotations.Service;

@Service(value = RedWineDataService.class)
@org.oasisopen.sca.annotation.Service(value = { RedWineDataService.class })
public class RedWineDataImpl implements RedWineDataService {
...

This code completes the composite code adaptation for Tuscany 2.0.

The Tuscany 2.0 test class—SCATesterT2—uses slightly different code to create the composite and call the service, as Listing 11 shows.

Listing 11. SCATesterT2
import org.apache.tuscany.sca.node.Contribution;
import org.apache.tuscany.sca.node.ContributionLocationHelper;
import org.apache.tuscany.sca.node.Node;
import org.apache.tuscany.sca.node.NodeFactory;

public class SCATesterT2 {

	public static void main(String[] args) {

		SCATesterT2 scaTester = new SCATesterT2();
		scaTester.testTuscany2();
	}

	void testTuscany2() {

		String contribution = ContributionLocationHelper
				.getContributionLocation(WineReviewService.class);

		Node node = NodeFactory.newInstance().createNode(
				"WineReview.composite", new Contribution(
							"test", contribution));

		node.start();

		WineReviewService wineService = node.getService(
				WineReviewService.class,
				"WineReviewComponent/WineReviewService");

		String result = wineService
				.getWineReview(WineReviewService.WINE_TYPE.RED);
		System.out.println(result);

		node.stop();
	}
}

The final step before retesting the scenario is to adjust the Eclipse run time configuration to isolate the run time CLASSPATHs of Tuscany 1.6 and 2.0. To do this, click the down arrow beside the Run button, and then click Run Configurations. Select the SCATesterT1 configuration (which was created by default when you ran that class), and then adjust the run time CLASSPATH so that only the project's /bin directory and the Tuscany16 user library are listed under User Entries. To do this, first remove the project's default CLASSPATH entry, and then add back /bin and the Tuscany16 user library, as shown in Figure 4.

Figure 4. Run time configuration
A screen shot of the Run configurations screen, with the selections described above

Do the same for SCATesterT2, replacing Tuscany16 with Tuscany20.

Finally, you're ready to test the composite with Tuscany 2.0, clicking Run to launch SCATesterT2 with the new configuration. Among the Tuscany 2.0 log messages, you should see:

This RED wine is full-bodied, evoking blackberries and tobacco

Troubleshooting and limitations

The SCA Tools plug-in for Eclipse cannot validate SCA 1.1 composite documents—even though the plug-in has a context menu proposing both types of files and diagrams. This effectively means that for the moment, all composite files and diagrams need to be created with the SCA 1.0 namespace and semantics and later adapted or augmented for SCA 1.1 run times.


Conclusion

This article reviewed SCA concepts and constructs. You imported and dissected a simplified composite application and test code and then configured a minimal Tuscany 1.0 environment in which to test the composite. Finally, you adapted the environment to Tuscany 2.0 (SCA 1.1), separating the run time CLASSPATHs and creating a separate test class with different constructs.

If you are new to SCA, you may want to take the next step and build a more complex SCA application using web services or other bindings that SCA offers. See Resources for links to more information.


Download

DescriptionNameSize
Sample scripts for this articlesrc.zip8KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Web development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development
ArticleID=549245
ArticleTitle=SCA revisited: Helios and Eclipse SCA tools
publish-date=10052010