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 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.
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.
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.
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.
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.
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.
Learn
-
Apache Tuscany
-
Open SOA Collaboration - SCA Specifications
- The SOA and Web services zone on IBM developerWorks hosts hundreds of informative articles and introductory, intermediate, and advanced tutorials on how to develop Web services applications.
- The IBM SOA Web site offers an overview of SOA and how IBM can help you get there.
- Stay current with developerWorks technical events and webcasts.
- Browse for books on these and other technical topics at the Safari bookstore.
Get products and technologies
- Innovate your next development project with IBM trial software, available for download or on DVD.
Discuss
- Participate in the discussion forum.
- Get involved in the developerWorks community by participating in developerWorks blogs.

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.
Comments (Undergoing maintenance)





