 | Level: Intermediate Andrew Borley (borley@uk.ibm.com), Software Engineer, IBM UK
22 May 2007 Service Component Architecture (SCA) is a set of specifications that describe a model for building applications and systems using a Service-Oriented Architecture. See how the Service Component Architecture can be used to build mashup applications.
Introduction
Service Component Architecture
provides a flexibility of composition, reuse, and technology and
deployment choice that makes it an ideal environment in which to build and run mashup applications.
This article describes the Alert Aggregator sample, a mashup style application with a Web 2.0 interface,
which has been recently developed for the Apache Tuscany
SCA Native runtime.
The Alert Aggregator sample application
 | | The code listings and Figure 1 in this article are copyright of The Apache Software Foundation 2007. |
|
The Alert Aggregator sample is a Web-based application that aggregates various sources of changing data
into a series of "alerts" that are displayed in an automatically updating Web page. Alert sources can include
RSS/Atom news feeds, POP3/IMAP e-mail, NNTP newsgroups, SOAP services (such as stock-quotes), and more.
SCA diagram
The diagram below details the SCA composites, components, external clients, and data sources and the wiring
between them all that composes the application.
Figure 1. SCA diagram
The sample runs inside the Tuscany runtime, itself hosted in an Apache HTTPD server. The server listens for
HTTPD requests to the SCA REST services and invokes the Tuscany runtime if such a request is received. Tuscany
then executes the appropriate components (as determined by the wiring) and returns the results in the HTTP
response. This means that calls from a standard Web browser can invoke an SCA service, which is what occurs in this
sample: the Web browser displays an HTML page, which contains JavaScript Ajax code. The Ajax calls invoke the SCA
components and the resulting data is displayed.
SCA elements
The Alerter Composite provides the main functionality of the application, aggregating data from different
sources (based upon the configuration) and presenting the collated data as XML from a REST service. The composite
contains the following components:
- The RSS/Atom Checker component gets the latest articles from a specified RSS or Atom feed and converts the
articles into a specified, simpler, XML format.
- The POP Checker component gets the latest e-mails from a specified POP3 e-mail account, again converting the
e-mails into the specified XML format.
- The NNTP Checker component gets the latest posts to a specified newsgroup on an NNTP server. This component
has not yet been implemented in the Alert Aggregator sample.
- The Web Service Checker component makes calls to a specified Web Service, converting the returned data into the
simple XML format. This component has not yet been implemented in the Alert Aggregator sample.
- The Alert Config component manages the configuration of the application, holding details about the RSS/Atom feeds
to retrieve, POP e-mail accounts to check, and more.
- The Alert Checker component manages the calls to the various Checker components based on the configuration data
provided by the Alert Config component. The XML data returned by the Checker components is aggregated into a single
XML document and is exposed to clients using a REST service binding.
The Display Composite provides functionality for converting the XML provided by the Alerter Composite into more
human-readable forms, such as HTML displayable in a Web browser. The composite contains the following components:
- The HTML Formatter component retrieves the configuration XML and the latest alerts XML from the Alerter Composite
and generates HTML tables based on that data. The HTML can be retrieved by Ajax calls from a Web page to a REST
service that exposes this component.
- The Text Formatter component also retrieves XML data from the Alerter Composite and formats it into
human-readable text for access by a local client. This component has not yet been implemented in the Alert Aggregator
sample.
Composite SCDL
SCA defines an XML language, Service Component Definition Language (SCDL), which allows developers to define the
components and the wiring between them. This XML is then processed and executed by the SCA runtime to produce the
running mashup. By making small changes to the SCDL, it is easy to reorder or replace components or add in new
functionality, enabling new mashups to be created. The SCDL for the Alerter Composite is as follows:
Listing 1. Alerter Composite SCDL
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="sample.alerter">
<service name="AlerterService">
<binding.rest/>
<reference>AlertCheckerComponent</reference>
</service>
<component name="AlertCheckerComponent">
<implementation.python module="AlertCheckerImpl" scope="composite"/>
<reference name="alertConfigService">AlertConfigComponent</reference>
<reference name="rssCheckerService">RSSCheckerComponent</reference>
<reference name="popCheckerService">POPCheckerComponent</reference>
</component>
<component name="RSSCheckerComponent">
<implementation.python module="RSSCheckerImpl" scope="composite"/>
</component>
<component name="POPCheckerComponent">
<implementation.python module="POPCheckerImpl" scope="composite"/>
</component>
<component name="AlertConfigComponent">
<implementation.python module="AlertConfigImpl" scope="composite"/>
</component>
</composite>
|
And the SCDL for the Display Composite is as follows:
Listing 2. Display Composite SCDL
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="sample.display">
<service name="HTMLDisplayService">
<binding.rest/>
<reference>HTMLDisplayComponent</reference>
</service>
<component name="HTMLDisplayComponent">
<implementation.python module="HTMLDisplayImpl" scope="composite"/>
<reference name="alertService">AlerterService</reference>
<property name="showNumberOfReadAlerts">20</property>
</component>
<reference name="AlerterService">
<binding.rest/>
</reference>
</composite>
|
From these two SCDL documents, you can see that all the components are implemented in Python
(as specified by the implementation.python elements) and the composite services are exposed using the
REST binding. These choices are not mandated by the SCA runtime; any of the components could be
implemented in any of the languages supported by the runtime, which currently includes C++, Python,
Ruby, and PHP for the Tuscany Native runtime. For instance, the sample includes a Ruby implementation
of the POPChecker component that could be swapped in to replace the Python implementation. Equally,
the choice of bindings used to expose a composite as a service can be easily changed, simply by
altering the SCDL. For example, the Alerter Composite could also be exposed as a SOAP Web Service.
The SCDL is the only place where the wiring between components is defined; the component
implementation code does not know which component or service is calling it or which component or
reference it is calling. This means that components are completely reusable; you can use the same
implementation in more then one mashup, simply configuring its references and properties
differently to produce a new mashup.
Component implementation
The Python implementation of the RSSChecker component is included below:
Listing 3. RSSChecker Python code
import feedparser, datetime, xml.etree.ElementTree, re
# Get new entries from an RSS/Atom feed
def getNewAlerts(rssaddress, lastchecktimestamp):
print "RSSCheckerImpl.getNewAlerts() called", rssaddress, lastchecktimestamp
# Get and parse the RSS/Atom data
d = feedparser.parse(rssaddress)
newalertsxml = "<alerts "
newalertsxml += xmlns=\"http://tuscany.apache.org/samples/alerter\">\n"
lastcheckdate = datetime.datetime.min
if lastchecktimestamp:
lastcheckdate = datetime.datetime.strptime(lastchecktimestamp,
"%Y-%m-%dT%H:%M:%S")
# Get default values from the feed attributes
defaultTitle = d.feed.get('title', 'RSS feed article')
defaultLink = d.feed.get('link', 'http://incubator.apache.org/tuscany')
defaultSummary = 'No information provided'
# Go through each entry in the feed and add it to the XML
for entry in d.entries:
if entry.has_key('date'):
(year, month, day, hour, minute, second, millisecond,
microsecond, tzinfo) = entry.date_parsed
entrydate = datetime.datetime(year, month, day, hour, minute, second)
else:
entrydate = datetime.datetime.now()
# Only append the latest alerts
if (entrydate > lastcheckdate) :
newalertsxml += "<alert><title>"
newalertsxml += stripXML(entry.get('title', defaultTitle)) + "</title>\n"
newalertsxml += "<address>" + entry.get('link', defaultLink)
newalertsxml += "</address>\n"
newalertsxml += "<date>" + entrydate.isoformat() + "</date>\n"
newalertsxml += "<summary>"
newalertsxml += stripXML(entry.get('description', defaultSummary))
newalertsxml += "</summary>\n"
newalertsxml += "</alert>\n"
newalertsxml += "</alerts>"
return xml.etree.ElementTree.XML(newalertsxml)
# Strips XML elements and entities out of a supplied string
def stripXML(data):
elementsRemoved = re.sub("<.*?>","", data)
entitiesRemoved = re.sub("&.*?;", " ", elementsRemoved)
asciiEncoded = entitiesRemoved.encode('ASCII', 'replace')
returnData = asciiEncoded.replace('&', 'and')
return returnData
|
From this code, you can see that the ElementTree Python library is being employed to return an
XML object. The Tuscany SCA Native runtime understands how to deal with ElementTree objects and will
convert them to the appropriate XML representation for transport or for processing in other components.
For instance, components implemented in Ruby use the Ruby REXML library to deal with XML data.
The following Python code details part of the AlertChecker component implementation:
Listing 4. AlertChecker Python code snippet
import xml.etree.ElementTree, datetime
def getAllNewAlerts ():
returnXML = "<alerts xmlns=\"http://tuscany.apache.org/samples/alerter\">\n"
returnXML += "</alerts>"
returnElem = xml.etree.ElementTree.XML(returnXML)
# Use the alertConfigService to get the configuration
configElem = alertConfigService.getAlertConfig()
ns = "./{http://tuscany.apache.org/samples/alerter}"
for sourceElem in configElem.findall( ns+"source"):
sourceid = sourceElem.attrib["id"]
newAlerts = getAlerts(sourceElem)
if xml.etree.ElementTree.iselement(newAlerts):
# Add the sourceid to each alert and append to the entire list
for alert in newAlerts.findall(ns+"alert"):
alert.attrib["sourceid"] = sourceid
returnElem.append(alert)
return returnElem
...
|
The above code shows how SCA references are handled within Python code running in the Tuscany
SCA Native runtime. In the snippet above, it looks as though the script is using an undefined variable
named "alertConfigService," but this is not the case. Tuscany automatically creates and adds a Python
proxy object (named "alertConfigService") to the loaded script. This proxy is wired to the referenced
component that is specified in the SCDL so that, when the alertConfigService.getAlertConfig() method
is called, the correct method on the referenced component is invoked.
SCA properties are handled in a similar way, with a Python object injected into the loaded script
and initialized to the specified value of the property.
Deploying and running the application
The sample runs within the Tuscany SCA Native runtime and is deployed to an Apache HTTPD server,
which hosts both composites (and serves their REST services) and serves the Web page user interface, as
well. The composites could just as easily be deployed to two separate HTTPD instances. The following
screenshots show the sample being demonstrated:
Figure 2. Alert Aggregator screenshot 1
The screenshot shown above in Figure 2 shows two RSS feeds being displayed, with the list of data sources at the top
(retrieved from the Alert Config component), the list of recent alerts below that (retrieved using the
Alert Checker and RSS Checker components), and an inline frame below that showing the details of a
particular alert.
Figure 3. Alert Aggregator screenshot 2
The screenshot shown above in Figure 3 shows the user adding a new alert source to the application. In this case it is a
POP e-mail account. When user clicks the Add button, the data is sent through to the Alert Config component
and added to the configuration.
Figure 4. Alert Aggregator screenshot 3
The screenshot shown above in Figure 4 shows the list of e-mails retrieved from the POP account. The user has also deleted
one of the two RSS data sources. One of the e-mails is being read in the bottom portion of the screen.
Conclusion
The Alert Aggregator sample shows how SCA and the Tuscany SCA runtime can be used to easily build mashup-style applications. You can easily add extra data-sources alongside the currently supported data-sources
simply by changing the SCDL and a few lines of code. The REST binding provided by Tuscany and hosted inside
Apache HTTPD means Web browsers can access the functionality provided by an SCA composite, enabling browser-based
clients. Finally, the support for multiple languages means that developers can employ their own skills and
pre-existing code and easily build up components into new applications that can then be rearranged and redeployed
into brand new mashups.
The Apache Tuscany project is always looking for input, suggestions, and contributions. Find out how
to get involved at the Tuscany Website.
Resources Learn
Get products and technologies
- Innovate your next development project with IBM trial software, available for download or on DVD.
Discuss
About the author  | 
|  | Andrew Borley is an IT Specialist at IBM Hursley, UK. He has held various roles including developer, team leader, and project manager and has worked with various technologies in his 7 years at IBM. Since 2001 he has been working with customers on Service-Oriented Architecture projects, and his current role is developing the SCA for C++ implementation within the Apache Tuscany open source SOA project. |
Rate this page
|  |