 | Level: Introductory Greg Flurry (flurry@us.ibm.com), Senior Technical Staff Member, IBM Software Group
01 Nov 2002 If you've downloaded version 3.2.2 of the Web Services Toolkit from IBM alphaWorks, you already have the Web Services Bus, a framework for constructing Web services processors. In this two-part series, Greg Flurry shows you how to get started using the Bus to get your Web services into production faster and more easily. In this first installment, you'll learn about the Bus's UDDI-based discovery mechanism, and examine an experimental practice that will help automate the process of publishing Web services.
The Web Services Bus, available in version 3.2.2 of the Web
Services Toolkit at IBM alphaWorks,
is a framework for constructing Web services
processors. With the Bus, you can create
Web service clients, servers, gateways,
intermediaries, and more (see Resources). The Bus goes beyond
other Web services frameworks to offer an
enhanced environment for conducting dynamic
e-business with Web services. It supports
service requestors with a client-side
on-ramp and supports service providers with a
server-side off-ramp. The Bus, through its Web Services Invocation
Framework (WSIF) heritage, has WSDL at its
core; Web services deployed in the bus off-ramp
(called bus services) can
be described with WSDL, and the off-ramp can
dynamically generate WSDL for bus services.
Further, the Bus off-ramp optionally publishes
information about bus services in UDDI registries.
In addition, the Bus supports formalized,
pluggable discovery and selection
mechanisms in the Bus on-ramp. Briefly, the
Bus accepts requests for a particular implementation
of a WSDL portType, but invokes the discovery
and selection mechanisms to direct
the requests to different implementations.
The pluggable discovery and selection mechanisms
can use any means desired to find candidate
implementations and subsequently select one
desired implementation from among the candidates.
The Bus prototype that is part of WSTK
3.2.2 includes a number of demonstrations
of the various capabilities of the Bus, including
a discovery mechanism based on WSIL. In this article, you'll learn
how to use various Bus capabilities
to implement a discovery mechanism based
on UDDI. Please see the documentation provided
with the Bus prototype implementation for
additional details. As you read through this series, you may find it useful to refer to the outline of the Bus architecture in Figure 1.
Figure 1. Web Services Bus architecture

General setup
Before you can run this article's example code,
you'll need to go through the initial setup
required to run anything associated with
the WSDK or the WSTK. First, you must install
and configure the Web Services Development
Kit, available from IBM developerWorks. The
WSDK includes an implementation of the private
UDDI registry needed for the example. Second, you must install and configure version 3.2.2 of the Web Services Toolkit, available from IBM alphaWorks; the WSTK includes the Web Services Bus prototype implementation. The
examples in this article assume that the WSTK is installed in the WSDK, but that is not strictly necessary; you must, however, configure the WSTK to use the private UDDI registry provided by the WSDK. You can find links to both the WSTK and the WSDK in the Resources section below.
Once you have installed both the WSDK and
the WSTK, you should start the WSDK (or whatever
Web application server you use) and try a
couple of things to confirm your installation.
First, you should point a new browser instance
at the GUI for the UDDI registry, accessible at http://<hostname:port>/uddigui/, where <hostname:port> represents the machine and port upon which
the UDDI registry is installed. Be sure to
log in using the default user name (demo) and default password (pwd), unless you have configured the WSTK
to use different values. You should see a page that looks something
like Figure 2 (you may have to resize
or scroll).
Figure 2. UDDI registry GUI

Next, you should confirm that the Bus prototype
works. Open a command window to WSTK_HOME/services/demos/wsbus/client, where WSTK_HOME denotes the directory where you installed
WSTK 3.2.2. Run one or more of the demos
in that directory; SimpleClientFilter.bat is a good one, as it tests both the client
and server sides of the Bus. If the demos
run successfully, you are ready to proceed
with additional setup.
Preparing the examples
There is a fair amount of setup specific
to the examples described in this article.
Before you can start running code, you'll need to:
- Create the JavaBeans that represent the service
implementations. This includes creating
the
WSDL that describes the service implementations.
- Prime the private UDDI registry. This includes
inserting a fictitious business that will
own the various entities created for the
example, and inserting a UDDI tModel that
corresponds to the WSDL portType implemented
by the service implementations above.
- Deploy the JavaBeans in the Bus as bus services.
- Test the deployed bus services.
I'll walk you through each step in turn.
Create the service JavaBeans
These examples use three implementations of
the ubiquitous stock quote service. Listing 1
shows the source for one of them, SQ1.java.
Listing 1. SQ1.java, a stock quote service
package gaf.uddi.sq;
public class SQ1 {
public float getQuote(String symbol) {
return (float) 155.25;
}
}
|
Notice that the incoming symbol is ignored
for simplicity's sake. The other service implementations,
SQ2.java and SQ3.java, are similar, but produce different values.
The source and class files for all three can be found in
the code package that accompanies this article. You must make the class files
for the beans available to the WSTK Web application;
do so by placing them in wstk.ear/wstk.war/WEB-INF/classes/gaf/uddi/sq relative to your Web application server's
installed applications directory.
The Bus supports several options for describing the
service implementations deployed in
it. This example uses the WSDL-only
option to ensure that the Bus recognizes that
all three services implement the same WSDL
portType. Listing 2 shows the
WSDL for the portType, SQ.wsdl, implemented by the JavaBeans SQ1, SQ2, and
SQ3.
Listing 2. WSDL for the portType implemented by the examples
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="SQ" targetNamespace="http://sq.uddi.gaf/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://sq.uddi.gaf/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<message name="getQuoteRequest">
<part name="symbol" type="xsd:string"/>
</message>
<message name="getQuoteResponse">
<part name="result" type="xsd:float"/>
</message>
<portType name="SQ">
<operation name="getQuote" parameterOrder="symbol">
<input message="tns:getQuoteRequest" name="getQuoteRequest"/>
<output message="tns:getQuoteResponse" name="getQuoteResponse"/>
</operation>
</portType>
</definitions>
|
Listing 3 contains SQ1Java.wsdl, the WSDL for the SQ1 implementation. Note
that the WSDL imports the portType in Listing 2, and contains a Java binding required for
deploying JavaBeans in the Bus using WSDL.
The WSDL code for SQ2 and SQ3 is identical, except
of course for the binding, service, and class
names.
Listing 3. SQ1Java.wsdl, WSDL for the SQ1 implementation
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="SQ1Java" targetNamespace="http://sq.uddi.gaf/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:format="http://schemas.xmlsoap.org/wsdl/formatbinding/"
xmlns:java="http://schemas.xmlsoap.org/wsdl/java/"
xmlns:tns="http://sq.uddi.gaf/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<import location="SQ.wsdl" namespace="http://sq.uddi.gaf/"/>
<binding name="SQ1JavaBinding" type="tns:SQ">
<java:binding/>
<format:typeMapping encoding="Java" style="Java">
<format:typeMap formatType="java.lang.String" typeName="xsd:string"/>
<format:typeMap formatType="float" typeName="xsd:float"/>
</format:typeMapping>
<operation name="getQuote">
<java:operation methodName="getQuote"
parameterOrder="symbol" returnPart="result"/>
<input name="getQuoteRequest"/>
<output name="getQuoteResponse"/>
</operation>
</binding>
<service name="SQ1Service">
<port binding="tns:SQ1JavaBinding" name="SQ1JavaPort">
<java:address className="gaf.uddi.sq.SQ1"/>
</port>
</service>
</definitions>
|
This WSDL is included in this article's code package. All
four WSDL files (SQ.wsdl, SQ1Java.wsdl, SQ2Java.wsdl, and SQ3Java.wsdl) must be placed in WEB-INF/wsbus/wsdl relative to your WSTK Web application installation.
Prime the private UDDI registry
The Bus off-ramp can optionally publish deployed
services into a UDDI registry according to
the best practices for publishing WSDL Web
services (see Resources for more on these best practices). In a later step, I'll leverage this capability to automatically
publish the services as they are deployed.
To enable the Bus to publish into the UDDI
registry, however, you must first publish
a business entity that will own the published
services. The default configuration for the
Bus off-ramp includes the name and description
of a business you can use; if for some reason
you have changed the default values for this business, you should
adjust the following steps accordingly.
You can use the UDDI registry GUI to publish
the business. Click on the Publish tab; then,
under Advanced Publish, click Add a Business.
Use "Placeholder" for the business
name, and "This holds services for WS
Bus" for the business description (assuming
the default Bus configuration). Then click
Publish Business. You'll see a confirmation
page. On the left panel of the GUI, scroll
down and click Show Owned Entities; you will
see something like Figure 3, which shows
that the user demo owns no service types, and owns a single
business with no services.
Figure 3. Owned entities screen from the UDDI registry GUI

As I've already briefly discussed, the Bus can optionally publish deployed services
in a UDDI registry according to an experimental practice that uses tModels to identify portTypes
as well as bindings. My example code leverages
this option to facilitate the discovery of implementations
of the stock quote service portType in the
registry. To publish the portType tModel
for the stock quote services above, copy
the batch file makeTModel.bat from this article's code package to WSTK_HOME/services/demos/wsbus/client, where WSTK_HOME refers to the directory where you installed
WSTK 3.2.2. The batch file has a hard-coded
URL referencing the stock quote portType
WSDL; if you have a different hostname or
port number, you will need to modify the
file. Once the batch file contains the correct
WSDL portType reference, execute it. If it
executes successfully, use the UDDI registry
GUI to show the owned entities once again.
You should see the information panel shown
in Figure 4.
Figure 4. Updated owned entity screen after execution of makeTModel.bat

Note the tModel named SQ, which corresponds
to the SQ portType. The other two tModels
are artifacts of the experimental practice, and
I won't need to discuss them further.
Deploy the JavaBeans
Now the JavaBeans that implement the stock
quote portType can be deployed in the Bus
prototype. To enable automatic publishing
in the UDDI registry, the registry itself
must be deployed in the Bus. Listing 4 contains
deployForUDDI.xml, the deployment descriptor used to deploy
the UDDI registry and the service implementations.
Listing 4. deployForUDDI.xml
<deploy force="true">
<uddiInfos>
<uddiInfo name="uddi1" userName="demo" password="pwd"
inquiryURL="http://localhost:80/uddisoap/inquiryapi"
publishURL="http://localhost:80/uddisoap/publishapi" />
</uddiInfos>
<busServices>
<busService serviceName="SQ1" audited="false" started="true"
configuredPartRep="1" resolvedPartRep="1" authorized="false"
uddiTModelName="UNSPSC" uddiKeyValue="84121801"
uddiKeyName="Stock market trading services"
portTypeNamespace="http://sq.uddi.gaf/" portTypeLocalName="SQ" >
<channels>
<channelReference channel="axis"/>
</channels>
<targetServices>
<targetService serviceName="SQ1Service" started="true" locationType="1"
location="http://localhost:80/wstk/wsbus/wsdl/SQ1Java.wsdl"
serviceNamespace="http://sq.uddi.gaf/" />
</targetServices>
<uddiReferences>
<uddiReference uddi="uddi1" />
</uddiReferences>
</busService>
<busService serviceName="SQ2" ... >
...
</busService>
<busService serviceName="SQ3" ... >
...
</busService>
</busServices>
</deploy>
|
The first element in Listing 4 contains information about
the private UDDI registry used in this example.
Depending on your hostname and port number,
you may have to edit the information about
the registry. The second element contains
information about the three service implementations;
full information is shown in Listing 4 only for SQ1, as
the others are identical except for the name
information. Each <busService> contains
attributes that indicate how to categorize
the bus service; in this case, the uddiTModelName,
uddiKeyValue, and uddiKeyName attributes
indicate (no surprise) that the services deal
with stock trading. Each <busService> also
contains attributes that indicate the portType
implemented by the service; in this case,
the portTypeNamespace and portTypeLocalName attributes correspond to the SQ portType
described above. As with the UDDI registry,
you may have to modify the hostname and port
number for the location of the WSDL documents
describing the services to match the appropriate
values for your own system.
To actually deploy the JavaBeans to the Bus
as bus services and automatically publish
the bus services in the UDDI registry, copy
the deployment descriptor deployForUDDI.xml from this article's code package to WSTK_HOME/services/demos/wsbus/client/deployment, then copy the batch file deployForUDDI.bat from the code package to WSTK_HOME/services/demos/wsbus/client. Run this batch file; if you see the message Results: OK, you have
successfully published the services.
To confirm publication, use the UDDI registry
GUI to show the owned entities. Figure 5
shows the result you'll get if you ask to show the services;
you should see all three services.
Figure 5. Registered business display showing services owned by the sample business

If you scroll down, you will see that there are
now additional tModels. The tModel named
SQApacheAxisBinding corresponds to the SOAP/HTTP binding, reflecting
the Apache Axis channel exposed by the Bus
prototype. The additional tModels are artifacts
of the experimental practice, and can be
ignored.
Test the Bus service
To test the deployment further, copy the
classfile for SQClient.java from this article's code package into WSTK_HOME/services/demos/wsbus/client/examples. Then copy the batch file runSQ.bat from the code package to WSTK_HOME/services/demos/wsbus/client. Listing 5 shows snippets of the
source for SQClient.java.
Listing 5. Partial source listing for SQClient.java
package services.demos.wsbus.client.examples;
public class SQClient {
static String serviceURL = null;
public float getQuote(String symbol) throws Exception {
System.out.println(
"Discovering and selecting a Stock Quote Service instance.");
QName qname = new QName("http://sq.uddi.gaf/", "SQ");
System.setProperty(
WSIFServiceFactory.WSIFFACTORY_CLASSNAME,
"com.ibm.wsbus.wsif.WSIFBusServiceFactory");
WSIFBusServiceFactory serviceFactory =
(WSIFBusServiceFactory) WSIFServiceFactory.newInstance();
WSIFService service = serviceFactory.getService(qname, serviceURL);
WSIFPort port = service.getPort();
WSIFOperation operation = port.createOperation("getQuote");
WSIFMessage input = operation.createInputMessage();
WSIFMessage output = operation.createOutputMessage();
WSIFMessage fault = operation.createFaultMessage();
System.out.println(
"Invoking the selected Stock Quote Service instance.");
input.setObjectPart("symbol", symbol);
operation.executeRequestResponseOperation(input, output, fault);
return output.getFloatPart("result");
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
usage();
return;
}
serviceURL = args[0];
String symbol = "XXX";
SQClient client = new SQClient();
float result = client.getQuote(symbol);
System.out.println(symbol + " = " + result);
}
}
|
The SQClient uses a WSIF-like technique to invoke a Web service, first using a service
factory to obtain a representation of the
service from the WSDL describing the service.
SQClient forces the use of a service factory
specialized for the Web Services Bus by setting
a system property appropriately. Because
the service factory is given a qualified name (a namespace
and local name, in this case) for service creation, it causes
the invocation of Bus discovery and selection
mechanisms at the time of service creation
in the Bus on-ramp.
The batch file runSQ.bat causes the client on-ramp to use the default
discovery and selection mechanisms installed
with the WSTK. These mechanisms simply return
the information given to them -- that is,
they allow the Bus on-ramp to emulate the
behavior of the standard WSIF. You will see this
when you execute runSQ, which you can do with the following syntax:
runSQ.bat "http://localhost/wstk/wsbus/ServiceDefinition?name=SQ<n>"
|
where <n> can be 1, 2, or 3, depending on which of the three services you want to invoke. Note that the URL for the service leverages the ability of the
Bus off-ramp to dynamically generate WSDL
for a deployed bus service.
If you execute runSQ.bat, you will see something
like Listing 6 in your command window.
Listing 6. Executing runSQ.bat: Results
C:\wstk-3.2.2\services\demos\wsbus\client>runSQ.bat "http://localhost/wstk/wsbus
/ServiceDefinition?name=SQ2"
***
Invocation of a Stock Quote Service -- default discovery and selection
***
Discovering and selecting a Stock Quote Service instance.
using WSIFServiceFactory
Sample Discovery: giving you what you gave me!
Sample Selection: giving you what you gave me!
Invoking the selected Stock Quote Service instance.
XXX = 255.25
|
Note the indication given by the sample discovery
and selection mechanisms that they are really
doing nothing. If you execute runSQ.bat for the
other bus services, you should see similar
results.
UDDI-based discovery
You are finally ready to try UDDI-based discovery,
as all the basic pieces are in place. As
a last step, you will need a custom discovery
implementation that uses the UDDI registry. Listing 7 contains snippets of the UDDI-based
discovery implementation.
Listing 7. Partial listing for the UDDI-based discovery implementation
package services.demos.wsbus.client.selection;
public class UDDIDiscovery implements BusDiscovery {
private PortTypeFinderUDDI finder = null;
public UDDIDiscovery() {
System.setProperty(
org.uddi4j.transport.TransportFactory.PROPERTY_NAME,
WSTKConstants.TRANSPORT_CLASS);
finder = new PortTypeFinderUDDI();
finder.setInquiryURL(WSTKConstants.UDDI_INQUIRY_URL);
}
public final Object[] discovery(QName portTypeQName, String wsdlReference)
throws WSBusException {
System.out.println("UDDI Discovery: finding services in UDDI!");
return find(portTypeQName);
}
public final Object[] discovery(
QName portTypeQName,
Definition wsdlDefinition)
throws WSBusException {
System.out.println("UDDI Discovery: finding services in UDDI!");
return find(portTypeQName);
}
private String[] find(QName portTypeQName) throws WSBusException {
String[] wsdlURL = null;
Vector wsdl = new Vector();
try {
BindingDetail bd =
finder.findImplementations(
portTypeQName.getNamespaceURI(),
portTypeQName.getLocalPart());
Vector btv = bd.getBindingTemplateVector();
for (int k = 0; k < btv.size(); k++) {
BindingTemplate bt = (BindingTemplate) btv.elementAt(k);
TModelInstanceDetails tmid = bt.getTModelInstanceDetails();
Vector tmidv = tmid.getTModelInstanceInfoVector();
for (int j = 0; j < tmidv.size(); j++) {
TModelInstanceInfo tmii =
(TModelInstanceInfo) tmidv.elementAt(j);
InstanceDetails id = tmii.getInstanceDetails();
if (id != null) {
OverviewDoc od = id.getOverviewDoc();
String oURL = od.getOverviewURLString();
// must remove port information
int p = oURL.indexOf('#');
wsdl.add(oURL.substring(0, p));
System.out.println(
"\tservice URL: " + oURL.substring(0, p));
}
}
}
wsdlURL = new String[wsdl.size()];
for (int k = 0; k < wsdl.size(); k++) {
wsdlURL[k] = (String) wsdl.elementAt(k);
}
} catch (Exception ex) {
throw new WSBusException(ex.getMessage());
}
return wsdlURL;
}
}
|
This discovery implementation creates an instance
of the Bus PortTypeFinderUDDI. In order to efficiently find those services, the findImplementations() method of this class leverages the artifacts
produced by the experimental practice used
to publish the bus services in the UDDI registry.
Fundamentally, the method simply searches
for UDDI bindingTemplates
that implement the desired WSDL portType --
in this case, the portType for the stock
quote services deployed in the Bus. The implementation
of the experimental practice in the Bus places
the URL for the service implementation WSDL
in the overviewURL in the tModelInstanceInfo
in the bindingTemplate. The discovery implementation
accumulates these URLs and returns them for
use by the selection mechanism.
In order to make the Bus on-ramp use the UDDI-based
discovery implementation, you must override
the sample implementation using a configuration
file. Listing 8 contains the configuration
file for the example, wsbusClientUDS.cfg.
Listing 8. wsbusClientUDS.cfg
<busInfo namespaceURI="" started="true"
discoveryClass="services.demos.wsbus.client.selection.UDDIDiscovery"
selectionClass="services.demos.wsbus.client.selection.RandomSelection">
</busInfo>
|
The configuration file establishes the UDDI-based
implementation described above as the Bus
discovery mechanism and a random selection
implementation installed with the WSTK as
the Bus selection mechanism; the latter makes
a random choice among the candidates given
to it.
To test the UDDI-based implementation, copy
the class file for UDDIDiscovery.java from this article's code package into WSTK_HOME/services/demos/wsbus/client/selection, then copy the configuration file wsbusClientUDS.cfg and the batch file uddiDiscoSQ.bat from the code package to WSTK_HOME/services/demos/wsbus/client. Finally, execute uddiDiscoSQ.bat. Your output should look something like Listing 9.
Listing 9. Testing the UDDI-based implementation: Results
C:\wstk-3.2.2\services\demos\wsbus\client>uddiDiscoSQ.bat
***
Invocation of a Stock Quote Service, UDDI discovery and random selection
***
Discovering and selecting a Stock Quote Service instance.
using WSIFServiceFactory
UDDI Discovery: finding services in UDDI!
FindTModel findPortTypeTModelKey() results: <?xml version="1.0" encoding="UTF-8"
?>
<tModelList generic="2.0" operator="operator" truncated="false" xmlns="urn:uddi-
org:api_v2">
<tModelInfos>
<tModelInfo tModelKey="UUID:389C138B-27FD-4E70-9AFD-0A3319622EC2">
<name>SQ</name>
</tModelInfo>
</tModelInfos>
</tModelList>
service URL: http://FLURRY:80/wstk/wsbus/ServiceDefinition?name=SQ3
service URL: http://FLURRY:80/wstk/wsbus/ServiceDefinition?name=SQ2
service URL: http://FLURRY:80/wstk/wsbus/ServiceDefinition?name=SQ1
Selecting #1
Retrieving document at 'http://FLURRY:80/wstk/wsbus/ServiceDefinition?name=SQ2'.
Retrieving import document at 'http://FLURRY:80/wstk/wsbus/ServiceInterface?name
=SQ2
Invoking the selected Stock Quote Service instance.
XXX = 255.25
|
As you go through Listing 9, you will see:
- An indication that the
Bus on-ramp uses the UDDI discovery implementation.
- A confirmation that the portType tModel exists
in the UDDI registry
- The results of the search in the UDDI registry
for implementations of the portType, that is,
the WSDL URLs for the three bus services
that implement the stock quote portType
- An indication of the candidate
chosen by the random selection mechanism
- The result of the invocation
of the selected service. The result depends on the service selected.
Restoring your WSTK
You may want to restore the Bus configuration
to the state it had before you ran the example
in this article -- that is, to undeploy the
bus services. You may also want to restore
the state of the UDDI registry used in this
example -- in other words, to delete the
various tModels, services, and other artifacts you created. Unfortunately,
a bug in the Bus off-ramp prevents it from
successfully unpublishing the services in
the UDDI registry automatically. You must manually delete the services from the UDDI
registry (you can use the UDDI registry GUI
to do so) before undeploying the stock quote
services in the Bus. Typically, the Bus,
and sometimes the UDDI registry, will hang
if you use the Bus to unpublish the services.
After you have deleted the services from
the UDDI registry, copy the file undeployForUDDI.xml from this article's code package into WSTK_HOME/services/demos/wsbus/client/deployment, then copy the batch file undeployForUDDI.bat from the code package to WSTK_HOME/services/demos/wsbus/client. Execute undeployForUDDI.bat; this undeploys the three stock quote services
and the UDDI registry from the Bus off-ramp
configuration. If you wish to do so, you
can now manually delete the tModels and the
business that you published in the UDDI registry
to run the example.
Conclusion
In this article, you learned about a number of aspects of the Web Services Bus related to WSDL, UDDI,
and Bus discovery. In particular, you learned how to create a UDDI registry-based discovery mechanism, and how to leverage an experimental practice implemented by the Bus to do efficient searches in a UDDI registry for services implementing a particular portType. A more
sophisticated discovery mechanism could examine
other UDDI registries, WSIL registries, databases,
or other sources of candidate implementations
for the portType. Similarly, though the sample code selects a service at random, a more sophisticated
selection mechanism could make an intelligent
choice, perhaps based on cost or service
level agreement terms, if such information
were available.
One final thought: Though the discovery implementation
in this example ran in the client on-ramp,
similar techniques can be used in the Bus's
server on-ramp. (For more on the server on-ramp, read the Bus documentation that comes with the WSTK.) This would allow the Bus server
side to be configured to do interesting things
as an intermediary, similar to the Web Services
Gateway, also available on alphaWorks. (See Resources.)
In this article, I explained how the unique features
of the Web Services Bus could be leveraged
to provide a UDDI-based mechanism for locating
and invoking implementations of a WSDL portType.
In a future article, I'll examine bus filters, another feature
of the Web Services Bus that enhances the Bus's abilities
as a framework for Web services.
Download | Name | Size | Download method |
|---|
| getbusresources.zip | | HTTP |
Resources
About the author  | 
|  | Greg Flurry is a member of IBM's Software Group Emerging Technologies, which investigates leading-edge technologies for a wide range of e-business environments. You can reach Greg at flurry@us.ibm.com.
|
Rate this page
|  |