Taking your first steps with SCA

Actually using Service Component Architecture

Part 2 In the first part of this two part series we introduced the Service Component Architecture (or SCA). SCA aims to make the construction of services simpler and less dependent on detailed knowledge of a range of different specifications within a Service Oriented Architecture (or SOA).

The previous column outlined the aims of SCA and provided an overall view of the approach it takes, In this column, we will look at how a simple Echo service can be implemented using SCA and examine a very simple JSP used to access that service.

Service Component Architecture

SCA is a specification created by the Open Service Oriented Architecture collaboration. The OSOA web site states that:

“The Open SOA Collaboration represents an informal group of industry leaders that share a common interest: defining a language-neutral programming model that meets the needs of enterprise developers who are developing software that exploits Service Oriented Architecture characteristics and benefits.”

As such, OSOA does not provide an implementation of SCA itself; instead, it provides the specifications for SCA on a royalty free basis. At present SCA is not a standard, although the intention is to hand the specifications over to a suitable standards organisation once the specifications have sufficiently matured.

To obtain an implementation of SCA you must either obtain the Apache Tuscany project or a vendor provided alternative (such as the IBM WebSphere Feature Pack for SOA). The Apache Tuscany incubator project provides an implementation of SCA for Java and C++. The current Java implementation builds on Tomcat and Apache Axis technologies. If you are working with WebSphere 6.1 then you can also obtain a version of the Tuscany project that pre-configures WebSphere such that it simplifies SCA construction.

Installing the Binary Distribution

To obtain the Tuscany implementation of SCA, you should download the binary distribution tuscany-sca-1.0-incubator-M2-bin.tar.gz or tuscany-sca-1.0-incubator-M2-bin.zip from the Tuscany download page. You can also obtain sample applications by downloading the samples distribution: tuscany-spec-sca-r0.95-incubator-M2-samples.tar.gz or tuscany-spec-sca-r0.95-incubator-M2-samples.zip. Alternatively, you can download WebSphere and install the SOA Feature Pack, to give you a specialised WebSphere version of SCA. Although it is a time-consuming process, the installation is very straightforward and is driven by a graphical installer.

A simple SCA Example

We will create a very simple SCA based Service using a simple Java class. The Java class to be used as the core implementation will receive a string, pre-fix it with another string and return the result. The service is the EchoService. It is defined in Java by an interface (EchoService) that defines the methods that will be published as part of the service. The implementation of this interface is provided by the EchoServiceImpl class, which also implements the service.

The EchoService Interface

The EchoService interface is presented below:

package com.reg.dev.sca;

import org.osoa.sca.annotations.Remotable;
import org.osoa.sca.annotations.Service;

/**
 * This is the business interface of the Echo Service.
 */
@Remotable
@Service
public interface EchoService {

    public String echo(String name);

}

As can be seen from this, it is a standard Java interface defining a single method echo that takes a string as a parameter. The only thing that marks it out from any other POJO is that it is annotated with @Remotable and @Service annotations from the org.osoa.sca.annotations package. This is one of the standard SCA packages. The Remotable annotation indicates that this is to be a service that can be accessed remotely (from outside the current deployment context). By default, services are only local, which means that they can only be accessed from within the current deployment. The Service annotation marks this interface out as defining the methods that will be published by the newly created service. All methods within the interface are automatically used to create the services interface.

The EchoServiceImpl class

The EchoServiceImpl class is presented below:


package com.reg.dev.sca;

import org.osoa.sca.annotations.Service;

/**
 * This class implements the Echo Service interface.
 */
@Service(EchoService.class)
public class EchoServiceImpl implements EchoService {

    public String echo(String string) {
        return "Hello Service World: " + string;
    }

}

Again, this illustrates that the implementation of the service is a normal Java class that implements the EchoService (although this is optional).

The EchoServiceImpl class is an example of a POJO (Plain Old Java Object) class. Its only special features are that it implements an EchoService interface and that an annotation @Service has been applied to the class. In fact both implementing the class and annotating the class, in this case, have exactly the same effect and only one is needed. The effect is to provide a link for SCA between the implementation class (i.e. EchoServiceImpl) and the definition of the Service Components operations (i.e. those methods defined in the EchoService interface). Thus a SCA implementation class need not directly implement the interface defining the service (as it can merely use the @Service annotation).

In this example, the String "Hello Service World: " pre-fixes the string passed in and this string is then returned as the result of the getEchoString method. The only thing which indicates that this is part of an SCA based service is the @Service annotation.

This is used to indicate which interface is to be used to determine the methods that are to be made publicly available as the interface of the service.

What you do beyond this point depends on how you intend to run your SCA application. At present, one of the two options is to use the Apache Tuscany project with Tomcat. The other option is to use the SOA Feature Pack for WebSphere 6.1. Both of these are available for evaluation. The SOA Feature Pack is essentially a pre-packaged version of Tuscany that reduces the amount of configuration you need to do to install a SCA application.

I've elected to use the WebSphere SOA Feature Pack, as this manages more of the configuration for me. This means that I must now create a Service Component Description Language file (sometimes referred to as a SCDL file) to define my service. The SCDL file for my simple service is presented below:

<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"  
           name="EchoComposite">
    <component name="EchoServiceComponent">
       <implementation.java class="com.reg.dev.sca.EchoServiceImpl"/>
    </component>
</composite>

This file states that I am creating a new Service component called EchoService and that the implementation for this service is provided by the class com.reg.dev.sca.EchoServiceImpl. This file can be complex, for services made up of multiple components wired together, but our example is very simple.

We are now ready to start building our application. The classes presented above were compiled using the IBM JDK using Java SE 5.0.

We can now write a client for our simple Service. In this column, for simplicity, I'll define a JSP which will uses SCA's own technologies to access the service. The HelloWorld.jsp JSP is presented below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
             pageEncoding="ISO-8859-1" autoFlush="true"
             import="com.reg.dev.sca.EchoService"
             import="org.osoa.sca.CurrentCompositeContext"
             import="org.osoa.sca.CompositeContext"
    %>
<TITLE>SCA Simple Example JSP</TITLE>
</HEAD>

<BODY>
<DIV align="center">
<P> </P>
<H2>SCA Simple Echo Example</H2>
<P> </P>

<%
try {
   // The SCA service is found in a lookup here
   CompositeContext compositeContext = CurrentCompositeContext.getContext();
   EchoService service = 
        (EchoService) 
             compositeContext.locateService(EchoService.class, 
                                                                     
                                            "EchoServiceComponent");
%>
        <h1>Hello Echo Service</h1>
        <P>
            <!-- Get output string from the service -->
            <%=service.echo("John")%>
        </P>
<%
}catch(Exception e){            
%>
    <%=e.getMessage()%>
<%}%>
</BODY>
</HTML>

In the above JSP the current SCA service contact is obtained via the getContext() method of the CurrentCompositeContext. The resulting CompositeContext object allows a service to be located by the name specified in the SCDL file (i.e. <component name="EchoServiceComponent">).

Once we have obtained a reference to the service, this can be cast to the service interface to allow access to the methods available on the Service. When a method is invoked by the JSP (that is service.echo(“John”)), the SCA runtime will dispatch the operation parameters to the correct method in the component implementation according to the definitions in the SCDL file. This will result in the EchoServiceImpl class being executed and the pre-fixed string being returned.

In our simplified example, this will produce an output on a web page generated form the result returned by the service.

Deploying the Service

To deploy the Service we package the Service and its JSP up into a single WAR (although this is not the only means of deploying this example). The WAR consists of the class files under WEB-INF/classes (as normal) along with the SCDL file (in the root of the classes directory). The JSP is in the root of the WAR and a simple web.xml file is defined for the web application. This web.xml file is presented below:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>Hello World Echo Sample</display-name>
</web-app>

The WAR file is then manually deployed to WebSphere with a root context of “hello”. This means that the JSP file can be accessed via the URL http://localhost:9080/hello/HelloWorld.jsp (9080 is the default port number when using WebSphere).

If we were to merely deploy this WAR file to a web server that knew nothing about SCA, then we would, at the very least, have runtime errors relating to the unknown annotations used with the classes. In addition, the SCDL file would be meaningless. However, as we have deployed the SOA Feature Pack for WebSphere, it already knows about SCA and how a WAR file that implements a service should be installed and managed. Thus in our case, when we access the JSP page the HelloWorld JSP interacts with the SCA framework and obtains a reference to the service allowing it to call the “echo” method and retrieve the resulting string. The end result is illustrated below in figure 1.

Shows the result of accessing the HelloWorld JSP.

Remote Web-based access

To access this via SOAP over HTTP we would need to define a WSDL file that would be used to map the web service to the underlying SCA implementation. We would then have to deploy the WSDL file along with the Service. This would be linked to the SCA component in the composite XML document using the following XML:

<reference name="EchoServiceReference">
       <interface.java interface="com.reg.dev.sca.EchoService" />
       <binding.ws endpoint="http://echo#wsdl.endpoint(EchoService/EchoSoapPort)"
location="wsdl/echo.wsdl" />
    </reference>

Summary

In this second column we have explored how an SCA component is implemented. As can be seen from the EchoService example, SCA is relatively straight forward and hides a great deal of the underlying plumbing form the developer. It can also be accessed through a variety of different mechanisms including RMI, Web Services, JMS etc. As such SCA is a very valuable tool available to designers and developers working with SOA based systems.®

Sponsored: 10 ways wire data helps conquer IT complexity