University of Wisconsin-Madison Skip navigationUW-Madison Home PageMy UW-MadisonSearch UW
 

 

Getting started with Middleware Web Services

Background and Basic Requirements

The general idea is that a web service is a client/server application which exchanges data in the form of XML documents. The protocol for doing this is called "SOAP" and all data is transported with HTTP. Other transport protocols can be used, but HTTP seems to be the most prevalent. The client and server need not be of the same architecture, operating system or programming language or even on the same network.

Web Services provide methods to applications as if those methods were from libraries installed locally.

In most programming environments, a "SOAP" object is instantiated and methods are called upon it using XML documents as inputs and outputs.

Consider a fictional identifier translation web service:

There is a method which accepts as input an XML document which represents a list of PeopleSoft "emplids." That method will do some processing and return an XML document which represents a list of Internet email addresses associated with those emplids. The application developer does need not to be concerned with the backend database operations which would most likely involve both Oracle (PeopleSoft) and LDAP (Sun One Directory Server 5.2).

All the developer has to do is first format the input XML correctly, pass it to the SOAP client then extract and process the response XML. It is difficult to learn how to do this at first in most languages since the XML is abstracted by object orientation, however in the long run it is easier then attempting to manage Oracle and LDAP connections and the structure of data in those stores.Middleware would write and maintain the method that does the translation from emplids to email and formats the output XML appropriately. Application developers are left to focus on what their business rules are and the proper format of the input XML.

Learning web services is a two step process of first figuring how the environment makes and configures SOAP objects and connections and then learning how to extract data from returned objects which represent XML documents.

Middleware has worked with SOAP clients in Perl,PHP,Java,Visual Basic 6.0 and VBScript(Microsoft Soap Toolkit 2.0). Middleware is most familiar with Perl based web services clients and can offer the most assistance if Perl is used as the client.There are a few technical requirements of the SOAP client software and these are:

  1. The client must be able to support the use of SSL Client certificates. (The security model of our server environment requires this.) If the client tool kit does not support client certificate exchange, HTTP Basic Authentication can be used if supported.
  2. The client must be able to connect to services utilizing a WSDL file. At this point of time, support for UDDI discovery services is not necessary.
  3. The client must support the document/literal wrapped style of SOAP. This is essentially the way Microsoft .NET works and is now a standard.
  4. The client must have some sort of XML processing capability.

With this in mind, some SOAP clients will work whereas others will not, even though they advertise "SOAP/web services" compatibility.

Our services operate as a shared infrastructure, so we try to avoid writing services that are specific to one particular project or application. We aim to write libraries of reusable code that can fit multiple sets of UW business models and rules.

WSDL Files, Toolkits and Web Services:

Okay, here's how you find out the information you need to know.

First go to a regular web browser and load in the WSDL file. The WSDL file describes which methods and XML documents a web service provides.

http://rpctest.services.wisc.edu/Test.wsdl

It is important that you understand the components of a WSDL file, there are many resources on the Internet. (Google it.)

But here's a quick HOWTO on extracting variables from WSDL files which you will need to specify when configuring your client's toolkit.

Go all the way to the bottom of the NetID.wsdl until you find the <wsdl:service> element. There you will find the service name and port names. Write these down, they are usually specified in most toolkits at the same time the url of the WSDL is specified.

Go back up a bit to the <wsdl:binding> element. There you will find all of the operations. These are the methods or operations (library functions) that can be called.

The notion of a class (e.g. a collection of methods) is called a portType in wsdl. You can find that by looking for the <wsdl:portType> element. Note that the method names are here as well. This is usually only important for .NET and Java clients as classes are built from the port types.

Check out the <wsdl:types> section for the format of XML input and output messages. Each method will have it's own format depending on the information it accepts or returns. This is expressed in XML Schema, which is something useful to be familiar with.

Some toolkits do all of this for you without needing to generate stub classes, shims or any other go-between and it works like this:

  1. Instantiate toolkit object with WSDL file, service name and desired port.
  2. Use XML libraries to make objects which represent XML
  3. Call web service methods on the toolkit object, pass XML object.
  4. Process the response using XML libraries.

Toolkits which do this:

  • Microsoft Soap ToolKit 3.0/2.0 (for VB6, VC++ 6)
  • PHP PEAR
  • Perl SOAP::Lite

Toolkits that generate proxy/stub classes which require more programming effort:

  • Microsoft .NET (!)
  • Apache Axis

Technical Details about our Web Services and WSDL files:

  1. There is only one portType (class) per WSDL file. It's name is "<service>PortType" eg NetIDPortType
  2. There is only one service and it's name is "<service>Service" eg NetIDService
  3. There are usually two publicly accessible ports defined for the service. One port describes a service endpoint/proxy for webservices which talk to each other. (eg via localhost) The other port describes the 'public' interface by which clients use the service over SSL.

    You will have to specify that you want to use the https port. It's usually named "<service>ServicePort" eg NetIDServicePort. You can't use the local port.

    If you have a toolkit that builds static code/classes from the WSDL in the ITE, then you move that code to production, it will still talk to the ITE (or try to) unless you rebuild the code from the production WSDL. The WSDL file locations are the same in production as in the ITE, however the service endpoints are different.

    NOTE: In production, endpoint is "https://rpc.services.wisc.edu/cert"

  4. The namespace / uri is http://rpc.services.wisc.edu/UWDS/WebService/<service>

    These uri's are used for defining namespaces and aren't actual web addresses where you can be expected to find things.,/p>

  5. The style of SOAP we do is not XML RPC.

    We do "Document Literal Wrapped" aka .NET style. This means that our responses are XML documents with no RPC style encoding. (eg 'literal') The documents are wrapped in an element called <operation>Response eg

    <getQuestionsResponse>...</getQuestionsResponse>

    The document elements may or may not have a namespace prefix depending on the type of document returned.

  6. We require the use of SSL.
  7. Client Certificates are used for authentication.

  8. MST's Certificate Authority will issue your client certificate.(Click here for instructions.)

Debugging

One of the best debugging aids is to actually look at the XML and HTTP headers on the wire as they go out. It's often easier to build a client looking at an example capture that works, then tweaking your code to produce the same result. Perl's SOAP::Lite client has a great debug switch that'll do just that.

Sample Code

#!perl

use UWDS::WebService;
use SOAP::Lite on_debug => sub { print @_; };

my $service = "NetID";
my $wsdl = "http://localhost/" . $service . ".wsdl";
my $servicename = $service . "Service";
my $port = $service . "LocalServicePort";
my $soap = SOAP::Lite->service($wsdl,$servicename,$port);
my %hash = ( uid=>"jeremyscott");
my @result = $soap->getQuestions(UWDS::WebService->format_soapdata(\%hash));

foreach my $question (@result) {
    print $question . "\n";
}

POST http://localhost/services
Accept: text/xml
Accept: multipart/*
Content-Length: 497
Content-Type: text/xml; charset=utf-8
SOAPAction: "UWDS/WebService/NetID#getQuestions"

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<getQuestions xmlns="http://rpc.services.wisc.edu/UWDS/WebService/NetID">
<uid>jeremyscott</uid>
</getQuestions>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Connection: close
Date: Fri, 05 Mar 2004 07:03:37 GMT
Server: Apache/1.3.29 (Unix) mod_perl/1.29
Content-Length: 638
Content-Type: text/xml; charset=utf-8
Client-Date: Fri, 05 Mar 2004 07:03:37 GMT
Client-Peer: 127.0.0.1:80
SOAPServer: SOAP::Lite/Perl/0.55
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<getQuestionsResponse xmlns="http://rpc.services.wisc.edu/UWDS/WebService/NetID">
<result>What is your quest?</result>
<result>What is your favorite colour?</result>
<result>What is the airspeed of a coconut-laden swallow?</result>
</getQuestionsResponse>
</SOAP-ENV:Body>

What is your question?
What is your favorite colour?
What is the airspeed of a coconut-laden swallow?

 
Middleware | UW Home