Service-Oriented Architecture: A brief introduction

[Originally published May 19, 2004]

What is SOA?

SOA, or Service-Oriented Architecture, is an architecture comprising

  • Loosely coupled services,
  • described by platform-agnostic interfaces
  • that can be discovered and invoked dynamically.

Loosely coupled refers to defining interfaces such that they are independent of each other’s implementation. In a loosely coupled system, you should be able to swap-out one of the components and replace it with another and cause no effect to the system. [10] attempts to pin down the exact implications of loosely coupled systems.

The platform-agnostic interface means that a client on any platform (OS, language, hardware) can consume the service.

Dynamic discovery implies some kind of registry where these services are listed, and which allows lookup.

Why is SOA interesting to businesses?

SOA protects your investments in legacy applications. So whether you have a Java application, a .NET application or even a COBOL application running on a mainframe- all are equal in a SOA architecture. [5] explains some of the importance of SOA to businesses. [11] is a Gartner report that predicts business acceptance trends for SOA.

Is Web services a SOA?

Yes. In Web services, WSDL is the platform-agnostic interface and UDDI is the registry where services are published and discovered from. The invocation is via SOAP messages on a variety of transports (HTTP, HTTPS, SMTP, JMS, roll-your-own-transport).

However, the converse need not be true- you can have a Service-Oriented Architecture without Web services, or even XML.

Is CORBA/DCE/DCOM/RMI a SOA ?

All distributed computing technologies are have a concept of services, are defined by interfaces, and are platform agnostic. However, for a variety of reasons- some technical and others not- Web services are emerging as the standard way to do services. [9] explains some of the differences between Web services and traditional distributed computing technologies.

References:

[1] IBM developerWorks. New to SOA and Web services. http://www-106.ibm.com/developerworks/webservices/newto/

[2] Kishore Channabasavaiah, Kerrie Holley et al. Migrating to a service-oriented architecture, Part 1. http://www-106.ibm.com/developerworks/webservices/library/ws-migratesoa/

[3] Kishore Channabasavaiah, Kerrie Holley et al. Migrating to a service-oriented architecture, Part 2. http://www-106.ibm.com/developerworks/webservices/library/ws-migratesoa2/

[4] Sayed Hashimi.Service-Oriented Architecture Explained. http://www.ondotnet.com/pub/a/dotnet/2003/08/18/soa_explained.html

[5] Todd Datz. What You Need to Know About Service-Oriented Architecture. http://www.cio.com/archive/011504/soa.html

[6] Easwaran G. Nadhan. Service-Oriented Architecture: Implementation Challenge. http://msdn.microsoft.com/architecture/default.aspx?pull=/library/en-us/dnmaj/html/aj2soaimpc.asp

[7] Todd Datz. What You Need to Know About Service-Oriented Architecture. http://www.cio.com/archive/011504/soa.html

[8] Hao He. What is Service-Oriented Architecture? http://webservices.xml.com/pub/a/ws/2003/09/30/soa.html

[9] Werner Vogels. Web Services are NOT Distributed Objects. http://weblogs.cs.cornell.edu/AllThingsDistributed/archives/000120.html

[10] Doug Kaye. Loose Coupling is Like Pornography. http://www.rds.com/doug/weblogs/webServicesStrategies/2002/11/18.html#a726

[11] Yefim Natis, Roy Schulte (Gartner). Introduction to Service-Oriented Architecture. http://mediaproducts.gartner.com/reprints/bea_systems/114295.html

Leave a Comment

Web service implementations

[Last updated on June 13, 2006]

A list I maintained of web service implementations. Please don’t send me an email about adding to this list- I no longer update this list. I’ve tried to classify implementations as:


Open source/free implementations

Product Company/Organization/Author Description
Apache SOAP Apache Software Foundation SOAP 1.2 implementation/Java
Apache Axis Apache Software Foundation SOAP 1.2 implementation/Java, C++
jUDDI Apache Software Foundation UDDI v2 implementation/Java
uddi4j IBM, HP UDDI v2 client API/Java
WSIF Apache Software Foundation An API for invoking Web services using WSDL descriptions/Java
Wingfoot SOAP Wingfoot Software J2ME implementation for SOAP/Java
kSOAP Stefan Haustein, James Seigel J2ME implementation for SOAP/Java
PocketSOAP Simon Fell SOAP implementation as a COM object/C++
SOAP::Lite Pavel Kulchenko SOAP implementation in Perl
PHP SOAP Shane Caraveo, Arnaud Limbourg SOAP implementation in PHP
gSOAP Robert A. van Engelen SOAP implementation in C++
SOAP4R NAKAMURA, Hiroshi SOAP 1.1 implementation in Ruby
Python web services project Various Web service libraries using the python programming language. These implement SOAP, WSDL, and other related protocols.

Commercial Web service stacks

Product Company/Organization/Author Description
IBM Websphere IBM Web service stack implemented as part of Websphere product line
Web Services Developer Pack (WSDP) Sun Microsystems Packages JAX* API, Security implementations, WSDP Registry Server, tools
WASP Server Systinet Web service stack (SOAP/WSDL/UDDI/WS-Sec) implementation in Java/C++
Microsoft .NET Framework Microsoft Microsoft’s Web service implementation
Oracle Application Server Oracle Web service stack implemented as part of Oracle Application server (10g) product line
BEA Weblogic BEA Web service stack implemented as part of Weblogic 8.x product line
webMethods GLUE webMethods Web service stack (SOAP/WSDL/UDDI/WS-Security) implementation in Java
BEA Weblogic BEA Web service stack implemented as part of Weblogic 8.x product line
Artix Enterprise Web Services IONA IONA’s Web Service Integration product
Sonic ESB Sonic Software Sonic’s Enterprise Service Bus implementation
RainingData RainingData SOA stack components- SOA Repository & Registry, ESB and Orchestration capabilities. Tools for SOA performance testing and process modeling
Blue Titan Network Director Blue Titan Software Deployment platform for Web services, provides routing, discovery, provisioning and monitoring.
Ivory GT Software SOA-enabling of mainframe applications

WS Composition products

Product Company/Organization/Author Description
Collaxa 2.0 Collaxa BPEL4WS implementation
BPWS4J IBM IBM’s BPEL4WS implementation

Security implementations: Hardware

Product Company/Organization/Author Description
XMS Message Server Westbridge XML/Web Services aware hardware firewall product. Supports XML encryption, signature, SAML in addition to standard transport level security implementations (DES/DES3, SHA, RSA etc.)
Reactivity XML Firewall Reactivity XML/Web Services aware hardware firewall product. Supports XML encryption, signature in addition to standard transport level security implementations (DES/DES3, SHA, RSA etc.)
Forum Sentry Forum Systems XML/Web Services aware hardware firewall product. Supports XML encryption, signature, SAML in addition to standard transport level security implementations (DES/DES3, SHA, RSA etc.)
XS40 XML Security Gateway DataPower SSL, XKMS, XACML, SAML, XML/SOAP firewall
Check Point VPN-1/FireWall-1 Checkpoint XML/SOAP firewall

Security implementations: Software

Product Company/Organization/Author Description
XKMS Implementation Verisign XKMS API implementation in Java
Trust Services Integration Kit (TSIK) Verisign Java API for creating trusted services, includes a SAML API
Apache XML-Security Apache Software Foundation Java and C++ implementations of XML Digital Signature and XML Encryption
XML Security Suite IBM Java implementation of XML Digital Signature, XML Encryption and XML Access Control Language and implementation
Oblix NetPoint Oblix Identity management software, supporting X.509, RSA SecureID, SAML
SunONE Identity Server Sun Microsystems Supports Liberty’s federated identity, and SAML
Microsoft Passport Microsoft Single sign-on support
Netegrity TransactionMinder Netegrity WS-Security, SAML
Quadrasis EASI Security Unifier Quadrasis WS-Security, SAML
RSA BSAFE Secure-WS RSA Security WS-Security implementation
VordelSecure Vordel WS-Security, SAML
BeSeQure – SOA Security BeSeQure Security framework based on WS-Security, SAML

Security implementations: Part of Web service stacks

Product Company/Organization/Author Description
IBM ETTK IBM Supports WS-Security, WS-Policy
Web Services Developer Pack Sun Microsystems Supports WS-Security, WS-Policy
Systinet WASP Systinet Supports WS-Security, SAML
.NET Microsoft Supports WS-Security

Tools

Title Company/Organization/Author Description
XMLSpy Altova SOAP debugger, WSDL editor features
SOAtest Parasoft Automated web service testing tool- WSDL validation, unit and functional testing of client and server, and performance testing
Mindreef SOAPScope Mindreef Tool for debugging, testing and performance tuning for Web services
WebServiceTester Optimyz Testing tool for Web services- functional, regression, performance, load and stress testing
StrikeIron Web Services Analyzer StrikeIron Visualization tool for Web services
jMeter Apache Software Foundation Open source framework for load testing functional behavior and measuring performance for Web applications and Web services
Test Maker Push To Test Testing software for reliability, functionality, scalability and performance.
Anteater Ovidiu Predescu, Jeff Turner Ant based testing framework for Web applications and Web services

Leave a Comment

Dealing with large data volumes in webservice calls

[Originally published June 27, 2005]

Once you start sending large volumes of data over a web service invocation, you often run into performance issue.

There are a range of techniques that can prove useful here:

  • Cache some of that information on the client side, instead of sending over everything for each webservice invocation. This is especially useful when some of the information to be sent over is relatively static
  • Paginate the information to be sent e.g. instead of sending over entire rows from a database select, send over the first 50, and let the client ask for the next 50 and so on. In this case there is a tradeoff between making multiple remote calls and one single call that returns a large chunk of data.
  • Have detail levels. An example of this is the UDDI API, where there a number of ‘find’ calls for returning things like ‘BusinessInfo’ list which doesn’t have all the data stored about a business- just the more commonly used pieces. Clients that need detailed information about a specific business or set of businesses can ‘drill down’ for more information. Again, you’d have a tradeoff here between making multiple remote calls and one single call.
  • Compress the data before sending it. This is covered in more detail here and here. The issues that this approach throws up relate to this being non-standard, and thus having an ad-hoc mechanism for getting the client and service agree on the compression mechanism.

Leave a Comment

Overcoming XML limitations for higher performance

[Originally published June 4, 2004]

Now that Web services are being considered for high performance applications- such as scientific computing- the limitiations of XML for messaging are being felt very acutely. No matter what you do for performance [3], once you try transferring huge amounts of, say biological data [5], your performance characteristics won’t be pretty. Its not just the size of the message that is a concern, it is also the overhead of doing a object->XML->object conversion.

There are multiple solutions that have been proposed for this:

  1. Compress the XML payload [5]. However, compression isn’t free, and so this approach has a tradeoff between processing and network overhead. Another problem is interoperability – though this can be overcome by specifying the compression protocol as a part of the payload.
  2. Use XML accelerators [1] that offload XML processing from Application servers to hardware. Sarvega and Data Power are two companies I know that offer these products.
  3. Use SOAP to negotiate a custom binary protocol, and then use that for data transfer [4].
  4. An interesting new approach is a Sun initiative called Fast Web services [2] or “Fast”. This uses a binary encoding for the SOAP payload. The higher level protocols (WSDL for contract definition of service etc.) remain unchanged, so in theory you could use standard SOAP-XML for development, and have a switch that turns on the binary protocol for production deployment. The binary protocol is not Java-only, and is standards based- Packed Encoding Rules (PER), also known as X.691. This protocol is a part of the ASN.1 family, and has been around for a while. Work is underway to map XSD to ASN.1. Fast is also backward compatible with non-Fast peers – the approach is “Use Fast when available, and use XML otherwise”.

This is an interesting area to watch- I personally like Fast approach. Sun was supposed to unveil a prototype version of Fast Web services in its Java Web Services Developer Pack (WSDP) early 2004, and I’m waiting for it.

References:

[1] Peter Lin. So You Want High Performance? http://jakarta.apache.org/tomcat/articles/performance.pdf

[2] Paul Sandoz, Santiago Pericas-Geertsen et al. Fast Web Services. http://java.sun.com/developer/technicalArticles/WebServices/fastWS/

[3] Vivek Chopra. Performance best practices for Web services. http://soaprpc.wordpress.com/2009/04/25/performance-best-practices-for-web-services/

[4] Madhusudhan Govindaraju, Aleksander Slominski et al. Requirements for and Evaluation of RMI Protocols for Scientific Computing. http://www.sc2000.org/techpapr/papers/pap.pap261.pdf

[5] Chetna Warade, Virinder Batra et al. Web services for bioinformatics, Part 2- Integrate high-throughput services with Web services. http://www-106.ibm.com/developerworks/library/ws-bioinfo2.html?ca=drs-ws2304

Update [June 18, 2004]: More information of Fast Web services and Fast infoset can be found here.

Leave a Comment

Registering and discovering RSS feeds in UDDI Business Registries

[Originally posted May 12, 2004]

CAVEAT: None of this code will probably work- UDDI Business Registries are so very 2001

Registering and Discovering RSS feeds

Finding new and interesting RSS feeds is a problem, and so is advertising your own feed. I explored a few websites that aggregate feeds, and wasn’t too satisfied with the experience.

Recently I found an article on Registering and Discovering RSS feeds in UDDI. Well I went and did just that at the IBM UBR node- here is my discover URL. I wrote up a small java program to browse the UDDI registry looking for RSS feeds, and didn’t find a whole lot. The ones I did find were the really good ones though- like Don Box’s Spoutlet, Karsten Januszewski’s UDDI Weblog, Tim Ewald’s Ideas about XML and Web Services … and offcourse now, your’s truly!

My java program source for searching RSS feeds is listed at the end of the post.

The RSS feeds I found (as on May 12, 2004) are listed below- many of them being weblogs of Microsoft folks.

Title URL
Don Box’s Spoutlet RSS 0.9, RSS 1.0
Drewby.net RSS 0.9
Jazz 88 News at KSDS-FM.org RSS 0.9
Karsten Januszewski’s UDDI Web Log RSS 0.9, RSS 1.0
Kirby T @thecave.com RSS 0.9,
Tim Ewald’s Ideas about XML and Web Services RSS 0.9, RSS 1.0
Vivek Chopra’s weblog on SOA and Web services RSS 1.0
Christian Weyer: Web Services & .NET RSS 2.0
Clemens Vasters: Enterprise Development & Alien Abductions RSS 2.0
Laurie Thompson-Earls RSS 2.0
Link to MSDN Just Published RSS 2.0
Matevz Gacnik’s Web Log RSS 2.0
Michael Earls RSS 2.0

Not a whole lot of feeds as you can see. Check out Syndic8 if you want more RSS feeds- 100,772 at last count (May 12, 2004)!

[Update 10:30 PM, May 12 2004] I found this great resource on RSS which has a lot of information on registering and discovering RSS feeds too.

Source code:

/**
 * This code is licensed under the following terms:
 *   Creative Commons Attribution-NoDerivs-NonCommercial 1.0
 *   http://creativecommons.org/licenses/by-nd-nc/1.0/
 *
 * Copyright (c) soaprpc.com. All rights reserved.
 */
package com.soaprpc.uddi4j.tools;

import org.uddi4j.*;
import org.uddi4j.client.*;
import org.uddi4j.datatype.*;
import org.uddi4j.datatype.assertion.*;
import org.uddi4j.datatype.binding.*;
import org.uddi4j.datatype.business.*;
import org.uddi4j.datatype.service.*;
import org.uddi4j.datatype.tmodel.*;
import org.uddi4j.request.*;
import org.uddi4j.response.*;
import org.uddi4j.transport.*;
import org.uddi4j.util.*;

import java.io.*;
import java.net.*;
import java.util.Properties;
import java.util.Vector;

/**
 * The FindRSSFeeds class is a command line based program that finds
 * RSS feeds.
 *
 */
public class FindRSSFeeds {

    /* tModel Key for RSS 0.9x feeds */
    public static String RSS_0_9_TMODELKEY = "uuid:8a056b70-bfe8-4fac-90cd-820c26dc2e48";

    /* tModel Key for RSS 1.0  feeds */
    public static String RSS_1_0_TMODELKEY = "uuid:bf3d12a4-a6e8-4ef2-918c-18c60a04edfc";

    /* tModel Key for RSS 2.0  feeds */
    public static String RSS_2_0_TMODELKEY = "uuid:bacbe300-4b2b-11d7-bc51-000629dc0a53";

    /* UDDI Inquiry URL              */
    public static String UDDI_INQUIRY_URL  = "http://uddi.ibm.com/ubr/inquiryapi";

    /**
     * The UDDIProxy object. All API calls to the UDDI registry are made against
     * this object.
     */
    private UDDIProxy _uddiProxy;

    public FindRSSFeeds (UDDIProxy uddiProxy) {
        _uddiProxy = uddiProxy;
    }

    /*
     * Utility method for dumping the DispositionReport
     */
    void printUDDIExceptionDetail(UDDIException uddiException, String message) {
        System.out.println(message + "\n");

        DispositionReport dispositionReport = uddiException.getDispositionReport();

        if (dispositionReport != null) {
            System.out.println("UDDIException faultCode:" +
                uddiException.getFaultCode() + "\n operator:" +
                dispositionReport.getOperator() + "\n generic:" +
                dispositionReport.getGeneric());

            Vector results = dispositionReport.getResultVector();

            for (int i = 0; i < results.size(); i++) {
                Result result = (Result) results.elementAt(i);
                System.out.println("\n errno:" + result.getErrno());

                if (result.getErrInfo() != null) {
                    System.out.println("\n errCode:" +
                        result.getErrInfo().getErrCode() + "\n errInfoText:" +
                        result.getErrInfo().getText());
                }
            }
        }
    }

    /* Find all RSS feeds */
    private void findRSSFeeds (String rssTModelKey) {
        ServiceList serviceList = null;

        try {
            TModelBag tModelBag = new TModelBag ();
            tModelBag.add (new TModelKey (rssTModelKey));
            /* Note:
             *  1. Set businessKey to "" to indicate that all businessEntities
             *     needs to be searched.
             *  2. Additional categoryBag entries can be added as needed, for
             *     instance to find all RSS feeds that belong to a specific
             *     classification. An example of this is to find all RSS feeds
             *     with NAICS category "Motion Picture and Video Industries".
             */
            serviceList = _uddiProxy.find_service("", null, null, tModelBag,
                                                  null, 0);

            /* Dump out useful information about the feeds */
           ServiceInfos serviceInfos = serviceList.getServiceInfos ();
           int size = serviceInfos.size();
           for (int i = 0; i < size; i++) {
              ServiceInfo serviceInfo = serviceInfos.get (i);
              String name             = serviceInfo.getDefaultNameString ();
              String serviceKey       = serviceInfo.getServiceKey ();
              ServiceDetail detail    =  _uddiProxy.get_serviceDetail(serviceKey);
              Vector serviceVector    = detail.getBusinessServiceVector ();
              BusinessService service = (BusinessService)serviceVector.get(0);
              BindingTemplate binding = service.getBindingTemplates().get(0);
              String accessPoint      = binding.getAccessPoint().getText();

              System.out.println ((i+1) + ". " + name + ": " + accessPoint + "\n");
           }        

        } catch (UDDIException e) {
            printUDDIExceptionDetail(e,
                "UDDI error searching for RSS feeds in UDDI Registry");
            System.exit(1); /* fatal error */
        } catch (Exception e) {
            System.out.println(
                "Exception searching for RSS feeds in UDDI Registry: " +
                e.getMessage());

            // e.printStackTrace ();
            System.exit(1); /* fatal error */
        }
    }

    /* Print usage message */
    private static void usage() {
        System.out.println("usage: FindRSSFeeds <rss09|rss10|rss20> [trace]");
        System.out.println("       The trace option enables SOAP message tracing");

    }

    public static void main(String[] args) {
        /* Process command line arguments */
        if (args.length < 1) {
            usage();
            System.exit(1);
        }

        /* Set up UDDI4J system properties */
        /* Set SOAP transport class to Apache SOAP */
        System.setProperty(TransportFactory.PROPERTY_NAME,
            "org.uddi4j.transport.ApacheSOAPTransport");

        /* Enable logging to dump messages to console */
        if ((args.length == 2) && (args[1].equals ("trace")))
            System.setProperty("org.uddi4j.logEnabled", "true");

        String inquiryUrl = FindRSSFeeds.UDDI_INQUIRY_URL;
        String rssVersion = args[0]; 

        /* Construct a UDDIProxy object- this represents a UDDI server
         * and the actions that can be invoked against it.
         */
        UDDIProxy uddiProxy = new UDDIProxy();

        /* Set the inquiry URL */
        try {
            uddiProxy.setInquiryURL(inquiryUrl);
            System.out.println("Using Inquiry URL [" + inquiryUrl + "]");
        } catch (MalformedURLException e) {
            System.out.println("Malformed publish URL for the UDDI registry [" +
                inquiryUrl + "]: " + e.getMessage());
            System.exit(1);
        }

        /* Make the inquiry call to the UDDI registry */
        FindRSSFeeds finder = new FindRSSFeeds (uddiProxy);

        if (rssVersion.equals("rss09")) {
            finder.findRSSFeeds (FindRSSFeeds.RSS_0_9_TMODELKEY);
        } else if (rssVersion.equals("rss10")) {
            finder.findRSSFeeds (FindRSSFeeds.RSS_1_0_TMODELKEY);
        } else if (rssVersion.equals("rss20")) {
            finder.findRSSFeeds (FindRSSFeeds.RSS_2_0_TMODELKEY);
        } else {
            usage();
        }
    }
}

Leave a Comment

Performance best practices for web services

[Originally posted May 11, 2004]

Performance is always a concern with Web services- there are better ways to designing a performant distributed system than sticking it behind a HTTP port and throwing verbose XML messages at it.

Lately I’ve been exploring some mechanisms to address performance issues for Web services. Most of these approaches target bottlenecks at the lower level SOAP layer, rather than at the design level. I’ve looked at some articles and technical papers that present metrics and guidelines. From them I’ve distilled the following performance best practices:

  • Design your Web service interface to minimize the network traffic. A ‘coarse-grained’ API is better, as you minimize the number of requests a client has to make to get information. [1][6]
  • Large SOAP messages are a performance bottleneck due to time spent parsing them. Keep your payload size as small as possible [1]
  • Complex SOAP message are a performance bottleneck due to time spent serializing/deserializing messages. Keep your payload complexity low. However, payload complexity and payload size are often design tradeoffs. [1]
  • SOAP intermediaries (gateways, proxies) should minimize parsing of messages.[1]
  • Better XML parsing techniques. [3] For most applications, event driven parsers (SAX style) are more performant than DOM style parsers.[1][6]
  • Document/Literal style SOAP messages are smaller and less complex than RPC/SOAP message. [1][5]
  • Security has performance costs. Not all SOAP traffic needs to be secure. The performance costs of an end-to-end security (i.e. WS-Security) is, in most cases, higher than a transport level security mechanism like SSL. [1]
  • Caching is a way to improve performance for processor-intensive services, though this is applicable only for read-only type of services. [2]
  • Many of the performance best practices for web applications will apply here too (using EJBs v/s JavaBeans, passing-by-reference of EJB components, Hardware and capacity settings, JVM setting etc.) [2]
  • Persistent connections are good for performance in case of a large number of messages of small payload size. For larger messages, this has less of an effect [3]. HTTP keep-alive is way [2] to request that a HTTP connection persist, though this is a default in HTTP/1.1.
  • Streaming connections are good for performance in case of a large payload size. HTTP ‘chunked encoding’ is a kind of streaming, and is supported by HTTP/1.1. [3][6]
  • Binary encoding of some payload elements should be considered. [3]

However, all said and done, remember the reasons for which you are choosing Web services – interoperability across heterogeneous environments- and not for performance!

References:

[1] Holt Adams. Web services performance considerations, Part 1. http://www-106.ibm.com/developerworks/library/ws-best9/

[2] Holt Adams. Web services performance considerations, Part 2. http://www-106.ibm.com/developerworks/webservices/library/ws-best10/

[3] Kenneth Chiu, Madhusudhan Govindaraju, et al. Investigating the Limits of SOAP Performance for Scientific Computing. http://www.extreme.indiana.edu/xgws/papers/soap-hpdc2002/soap-hpdc2002.pdf

[4] Madhusudhan Govindaraju, Aleksander Slominski et al. Requirements for and Evaluation of RMI Protocols for Scientific Computing. http://www.sc2000.org/techpapr/papers/pap.pap261.pdf

[5] Frank Cohen. Discover SOAP encoding’s impact on Web service performance http://www-106.ibm.com/developerworks/webservices/library/ws-soapenc/

[6] Dan Davis and Manish Parashar. Latency Performance of SOAP implementations http://www.caip.rutgers.edu/TASSL/Papers/p2p-p2pws02-soap.pdf

[Update May 12, 2004] I found another website that consolidates performance best practices.

Comments (1)

web service specifications

[Originally updated September 2005]

My attempt to keep track of all the web service specifications…

Standard Current version URL
SOAP 1.2 http://www.w3.org/TR/soap
SOAP with Attachements - http://www.w3.org/TR/SOAP-attachments
WS-Attachments - http://www-106.ibm.com/developerworks/webservices/library/ws-attach.html
WSDL 1.1 http://www.w3.org/TR/wsdl
UDDI 2, 3 in progress http://www.uddi.org/specification.html
WS-Inspection 1.0 http://www-106.ibm.com/developerworks/webservices/library/ws-wsilspec.html
BPEL4WS 1.1 http://www-106.ibm.com/developerworks/library/ws-bpel/
WS-Coordination - http://www-106.ibm.com/developerworks/library/ws-coor/
WSCI 1.0 http://www.w3.org/TR/wsci/
BPML 1.0 http://www.bpmi.org/specifications.esp
WS-Transaction - http://www.ibm.com/developerworks/library/ws-transpec/
WS-ReliableMessaging - http://www-106.ibm.com/developerworks/webservices/library/ws-rm/
XML-Signature - http://www.w3.org/Signature/
XML-Encryption - http://www.w3.org/Encryption/
XKMS - http://www.w3.org/TR/xkms/
WS-Security - http://www-106.ibm.com/developerworks/webservices/library/ws-secure/
SAML 1.1, 2.0 in progress http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=security
XACML 1.0, 1.1 in progress http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml
Passport - http://msdn.microsoft.com/library/default.asp?url=/downloads/list/websrvpass.asp
Liberty - http://www.projectliberty.org/
WS-Federation - http://www-106.ibm.com/developerworks/webservices/library/ws-fed/
WS-Trust - http://www.ibm.com/developerworks/library/ws-trust/index.html
WS-Policy - http://www-106.ibm.com/developerworks/library/ws-polfram/
WS-SecurityPolicy - http://www-106.ibm.com/developerworks/library/ws-secpol/
WS-SecureConversation - http://www-106.ibm.com/developerworks/library/ws-secon/
WS-Authorization Work in progress Work in progress
XrML 2.0 http://www.xrml.org/get_XrML.asp
WS-Privacy Work in progress Work in progress
WS-Notification - http://www-106.ibm.com/developerworks/library/specification/ws-notification/
WS-ResourceFramework - http://www-106.ibm.com/developerworks/library/ws-resource/
WS-Eventing - http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dnglobspec/html/ws-eventing.asp

Leave a Comment

Browsing UDDI registries

[Originally posted on March 23, 2004 ]

CAVEAT: None of this code will probably work- UDDI Business Registries are so very 2001

Some years back (2001?) I had written up a very primitive command line tool to dump data from a UDDI (then V1) registry. I recently updated it for the current version of uddi4j.

The command tool was very optimistically named ‘UDDI Browser’ (source listed at end of article). It enabled you to do things like:

Find a business by name

java com.soaprpc.uddi4j.tools.UDDIBrowser http://uddi.ibm.com/ubr/inquiryapi find_business name ibm

Look at the list of business returned, and drill-down using a business key

java com.soaprpc.uddi4j.tools.UDDIBrowser http://uddi.ibm.com/ubr/inquiryapi find_business key D2033110-3AAF-11D5-80DC-002035229C64

On finding a service you like, you can get information on it:

java com.soaprpc.uddi4j.tools.UDDIBrowser http://uddi.ibm.com/ubr/inquiryapi find_service key 894B5100-3AAF-11D5-80DC-002035229C64

The prerequisites for the code are:

  • Apache SOAP- uddi4j works with Axis, however I had problems with the current Axis release. I haven’t verified which Axis version uddi4j works with. however you should use Xerces due to a bug with Crimson- see my comment below. You would have to make a small, one line change in the code to set the correct SOAP transport class.
  • Java mail (required by Apache SOAP)
  • Java activation framework (required by Apache SOAP)
  • And offcoure, uddi4j. Further instructions are here.

Note that if you run this software from behind a proxy server, you would need to specify the proxy host and port at the command line using -Dhttp.proxyHost/-Dhttp.proxyPort.

Most commercial Web service products include a UDDI browser, but if you are looking for an open source/free option and don’t like the primitive interface of my UDDI tool, you do have some options. Many moons ago I worked briefly on one such tool- the now defunct HP Registry Composer. I found a datasheet for it still around on the ‘HP Middleware’ website. Your other (non-defunct) options include soapclient’s web based UDDI browser and an open source SWING based tool called uddibrowse (I’ve seen some screenshots, but haven’t tried it out).

The public UDDI registries (UDDI Business Registry- UBR) have a web based interface too. Uddi4j’s website lists them, but is outdated- it still has HP’s UBR site listed (HP dropped most it’s Web Service offerings about a year and a half/two years ago), and the Microsoft UBR address is incorrect. A complete list is:

IBM-Production
Registration web site https://uddi.ibm.com/ubr/registry.html
Inquiry URL http://uddi.ibm.com/ubr/inquiryapi
Publish URL https://uddi.ibm.com/ubr/publishapi
Microsoft-Production
Registration web site http://uddi.microsoft.com
Inquiry URL http://uddi.microsoft.com/inquire
Publish URL https://uddi.microsoft.com/publish
SAP-Production
Registration web site http://uddi.sap.com
Inquiry URL http://uddi.sap.com/UDDI/api/inquiry/
Publish URL https://uddi.sap.com/UDDI/api/publish/

If you are planning to publish to the UDDI registry, you should use the ‘test’ registries. These currently support UDDI V3 Beta, and are backwards compatible with the UDDI V2 API.

IBM-Test
Registration web site https://uddi.ibm.com/beta/registry.html
Inquiry URL http://uddi.ibm.com/beta/inquiryapi
Publish URL https://uddi.ibm.com/beta/publishapi
Microsoft-Test
Registration web site http://uddi.beta.microsoft.com
Inquiry URL http://uddi.beta.microsoft.com/inquire
Publish URL https://uddi.beta.microsoft.com/publish
SAP-Test
Registration web site http://udditest.sap.com
Inquiry URL http://udditest.sap.com/UDDI/api/inquiry/
Publish URL https://udditest.sap.com/UDDI/api/publish/

Source code for UDDIBrowser  (see the circa 2001 usage of java.util.Vector!)

/**
 * This code is licensed under the following terms:
 *   Creative Commons Attribution-NoDerivs-NonCommercial 1.0
 *   http://creativecommons.org/licenses/by-nd-nc/1.0/
 *
 * Copyright (c) soaprpc.com. All rights reserved.
 */
package com.soaprpc.uddi4j.tools;

import org.uddi4j.*;
import org.uddi4j.client.*;
import org.uddi4j.datatype.*;
import org.uddi4j.datatype.assertion.*;
import org.uddi4j.datatype.binding.*;
import org.uddi4j.datatype.business.*;
import org.uddi4j.datatype.service.*;
import org.uddi4j.datatype.tmodel.*;
import org.uddi4j.request.*;
import org.uddi4j.response.*;
import org.uddi4j.transport.*;
import org.uddi4j.util.*;

import java.io.*;
import java.net.*;
import java.util.Properties;
import java.util.Vector;

/**
 * The UDDIBrowser class is a command line based UDDI registry browser
 *
 * @author Vivek Chopra (www.soaprpc.com)
 */
public class UDDIBrowser {
    /**
     * The UDDIProxy object. All API calls to the UDDI registry are made against
     * this object.
     */
    private UDDIProxy _uddiProxy;

    public UDDIBrowser(UDDIProxy uddiProxy) {
        _uddiProxy = uddiProxy;
    }

    /*
     * Utility method for dumping the DispositionReport
     */
    void printUDDIExceptionDetail(UDDIException uddiException, String message) {
        System.out.println(message + "\n");

        DispositionReport dispositionReport = uddiException.getDispositionReport();

        if (dispositionReport != null) {
            System.out.println("UDDIException faultCode:" +
                uddiException.getFaultCode() + "\n operator:" +
                dispositionReport.getOperator() + "\n generic:" +
                dispositionReport.getGeneric());

            Vector results = dispositionReport.getResultVector();

            for (int i = 0; i < results.size(); i++) {
                Result result = (Result) results.elementAt(i);
                System.out.println("\n errno:" + result.getErrno());

                if (result.getErrInfo() != null) {
                    System.out.println("\n errCode:" +
                        result.getErrInfo().getErrCode() + "\n errInfoText:" +
                        result.getErrInfo().getText());
                }
            }
        }
    }

    /* Browse by Business Name- return all matching business entities */
    private void browseBusinessByName(String businessName) {
        BusinessList businessList = null;

        try {
            Vector names = new Vector();
            names.add(new Name(businessName));

            businessList = _uddiProxy.find_business(names, null, null, null,
                    null, null, 0);
        } catch (UDDIException e) {
            printUDDIExceptionDetail(e,
                "UDDI error browsing for businesses in UDDI Registry");
            System.exit(1); /* fatal error */
        } catch (Exception e) {
            System.out.println(
                "Exception browsing for businesses in UDDI Registry: " +
                e.getMessage());

            // e.printStackTrace ();
            System.exit(1); /* fatal error */
        }

        /* Since logging is enabled, all request and response messages will be
         * dumped to console
         */
    }

    /* Browse by Business key- return an entire businessEntity */
    private void browseBusinessByKey(String businessKey) {
        Vector vector = new Vector();
        vector.addElement(businessKey);

        BusinessDetail businessDetail = null;

        try {
            businessDetail = _uddiProxy.get_businessDetail(vector);
        } catch (UDDIException e) {
            printUDDIExceptionDetail(e,
                "UDDI error browsing for businesses in UDDI Registry");
            System.exit(1); /* fatal error */
        } catch (Exception e) {
            System.out.println(
                "Exception browsing for businesses in UDDI Registry: " +
                e.getMessage());

            // e.printStackTrace ();
            System.exit(1); /* fatal error */
        }

        /* Since logging is enabled, all request and response messages will be
         * dumped to console
         */
    }

    /* Browse by Service key- return an entire businessService */
    private void browseServiceByKey(String businessServiceKey) {
        Vector vector = new Vector();
        vector.addElement(businessServiceKey);

        ServiceDetail serviceDetail = null;

        try {
            serviceDetail = _uddiProxy.get_serviceDetail(vector);
        } catch (UDDIException e) {
            printUDDIExceptionDetail(e,
                "UDDI error browsing for services in UDDI Registry");
            System.exit(1); /* fatal error */
        } catch (Exception e) {
            System.out.println(
                "Exception browsing for services in UDDI Registry: " +
                e.getMessage());

            // e.printStackTrace ();
            System.exit(1); /* fatal error */
        }

        /* Since logging is enabled, all request and response messages will be
         * dumped to console
         */
    }

    /* Browse by tModel Name- return all matching tModel infos */
    private void browseTModelByName(String tModelName) {
        TModelList tModelList = null;

        try {
            tModelList = _uddiProxy.find_tModel(tModelName, null, null, null, 0);
        } catch (UDDIException e) {
            printUDDIExceptionDetail(e,
                "UDDI error browsing for tModels in UDDI Registry");
            System.exit(1); /* fatal error */
        } catch (Exception e) {
            System.out.println(
                "Exception browsing for tModels in UDDI Registry: " +
                e.getMessage());

            // e.printStackTrace ();
            System.exit(1); /* fatal error */
        }

        /* Since logging is enabled, all request and response messages will be
         * dumped to console
         */
    }

    /* Browse by tModel key- return a TModelDetail structure */
    private void browseTModelByKey(String tModelKey) {
        Vector vector = new Vector();
        vector.addElement(tModelKey);

        TModelDetail tModelDetail = null;

        try {
            tModelDetail = _uddiProxy.get_tModelDetail(vector);
        } catch (UDDIException e) {
            printUDDIExceptionDetail(e,
                "UDDI error browsing for tModels in UDDI Registry");
            System.exit(1); /* fatal error */
        } catch (Exception e) {
            System.out.println(
                "Exception browsing for tModels in UDDI Registry: " +
                e.getMessage());

            // e.printStackTrace ();
            System.exit(1); /* fatal error */
        }

        /* Since logging is enabled, all request and response messages will be
         * dumped to console
         */
    }

    /* Print usage message */
    private static void usage() {
        System.out.println(
            "usage: UDDIBrowser <inquiry_url> <find_business|find_service|find_tmodel> <options>\n" +
            "             <options> are :\n" +
            "             [for find_business]\n" +
            "             name <partial_business_name>\n" +
            "             key  <businessKey>\n\n" +
            "             [for find_service]\n" +
            "             key  <serviceKey>\n\n" +
            "             [for find_tmodel]\n" +
            "             name  <partial_tmodel_name>\n" +
            "             key  <tModelKey>");
    }

    public static void main(String[] args) {
        /* Process command line arguments */
        if (args.length < 2) {
            usage();
            System.exit(1);
        }

        /* Set up UDDI4J system properties */
        /* Set SOAP transport class to Apache SOAP */
        System.setProperty(TransportFactory.PROPERTY_NAME,
            "org.uddi4j.transport.ApacheSOAPTransport");

        /* Enable logging to dump messages to console */
        System.setProperty("org.uddi4j.logEnabled", "true");

        String inquiryUrl = args[0];

        String inquiryMethod = args[1];

        if (!inquiryMethod.equals("find_business") &&
                !inquiryMethod.equals("find_service") &&
                !inquiryMethod.equals("find_tmodel")) {
            System.out.println("Inquiry method '" + inquiryMethod +
                "' not valid- has to be one of find_business|find_service|find_tmodel");
        }

        /* Construct a UDDIProxy object- this represents a UDDI server
         * and the actions that can be invoked against it.
         */
        UDDIProxy uddiProxy = new UDDIProxy();

        /* Set the inquiry URL */
        try {
            uddiProxy.setInquiryURL(inquiryUrl);
            System.out.println("Using Inquiry URL [" + inquiryUrl + "]");
        } catch (MalformedURLException e) {
            System.out.println("Malformed publish URL for the UDDI registry [" +
                inquiryUrl + "]: " + e.getMessage());
            System.exit(1);
        }

        /* Make the inquiry call to the UDDI registry */
        UDDIBrowser browser = new UDDIBrowser(uddiProxy);

        if (inquiryMethod.equals("find_business")) {
            if (args[2].equals("name")) {
                browser.browseBusinessByName(args[3]);
            } else if (args[2].equals("key")) {
                browser.browseBusinessByKey(args[3]);
            } else {
                usage();
            }
        } else if (inquiryMethod.equals("find_service")) {
            browser.browseServiceByKey(args[3]);
        } else if (inquiryMethod.equals("find_tmodel")) {
            if (args[2].equals("name")) {
                browser.browseTModelByName(args[3]);
            } else if (args[2].equals("key")) {
                browser.browseTModelByKey(args[3]);
            } else {
                usage();
            }
        } else {
            usage();
        }
    }
}

Leave a Comment

web service standards

[Originally posted on March 17, 2004]

Some time back, I was preparing a document on Web service standards- specifically security related ones- and was overwhelmed by the sheer number of them. I wrote up this rough guide to the Web services ‘alphabet soup’ to help me get a big picture of what the standards are, and where they fit in.

Basic standards

  • SOAP (Simple Object Access Protocol) defines the format of messages on the ‘wire’.
  • WSDL (Web Services Description Language) is used to describe the programmatic interface exposed by a Web Service, and (optionally) the URL for accessing it.
  • UDDI (Universal Description, Discovery and Integration) allows for discovery of not just Web services, but also supports a more general ‘yellow page’ lookup for companies and services that they provide.
  • WS-Inspection is a lightweight discovery standard being pushed by Microsoft and IBM that merges their earlier efforts- IBM’s Advertisement and Discovery of Services (ADS) and Microsoft’s Discovery of Web Services (DISCO).

The discovery standards haven’t (as of date) had a lot of traction. SOAP & WSDL on the other hand, are widely in use.

Web service Composition standards

  • BPEL4WS (Business Process Execution Language for Web Services) consolidates Microsoft’s XLANG and IBM’s Web Services Flow Language (WSFL)
    • WS-Coordination is used along with BPEL4WS for coordinating services
    • WS-AtomicTransaction defines the atomic transaction coordination type used by WS-Coordination specification.
  • WSCI (Web Service Choreography Interface)- Sun’s alternative to BPEL4WS. It is now a W3C Note, however BPEL4WS has had more acceptance in the market.
  • BPML (Business Process Modeling Language)- been around longer than the other standards, but doesn’t have backing from any major enterprise software company. Ok, BEA is listed as a member, BEA is also an author for BPEL4WS and WSCI. Go figure!

These three competing standards allow for workflow-type applications with Web services.

Web Service QoS standards

  • WS-Transaction defines a transaction model for Web Services.
  • WS-ReliableMessaging deals with reliably delivery of messages between Web Services and client applications.

Security Standards

Security for Web services can be achieved at two levels- either at the ‘wire’ level or at an XML level. Wire level security, also called Transport layer security uses existing Internet protocols to secure the traffic between the Web Service and the client application. For example you can use:

  • HTTP based authentication (HTTP BASIC, HTTP Digest, HTTP CLIENT-CERT)
  • SSL for encrypting data
  • Either a custom access control mechanism, or a J2EE/Realm based access control

Wire level security is fine so long you have one Web Service provider and a simple security policy. However, things become difficult if you have a number of Web Service providers, or a document being passed around by different services (such as in a workflow). This is because transport layer security mechanisms only secure the information exchange between two application endpoints: they do not provide for an end-to-end security model.

In XML level security, also called Message level security, the security information and access policies are bundled in the message itself. There is a long list of standards in this space, though the ones that have some market acceptance at the moment are XML-Encryption, XML-Signature (also used as a part of WS-Security) and SAML.

  • The basic Message level security standards
    • XML-Signature is an XML syntax for digital signatures
    • XML-Encryption specifies how an XML can be used to represent a digitally encrypted web resource, including another XML document
    • XKMS is a protocol for distributing and registering public keys, and is intended to be used along with XML-Signature.
    • WS-Security is a protocol neutral mechanism for securing SOAP messages. It builds upon XML-Signature and XML-Encryption, and also specifies how security tokens can be associated with messages.
  • Security token standards
  • These standards aim to enable interoperable authentication and authorization across systems. This is done by having security tokens bundled along with a SOAP message, and these tokens can be in any format, such as:

    X.509 and Kerberos have been around for a long time- they pre-date Web Services. SAML (Security Assertion Markup Language ) is however getting a lot of commercial attention, and has a number of implementations. There is another standard with some overlap to SAML called XACML (eXtensible Access Control Markup Language), which, as the name suggests, is an access control rule language.

  • Identity

    Liberty and Passport try to solve the same problem (single sign on, identity) but approach it differently. Liberty has a federated architecture and is based on SAML. It consists of a set of specifications and depends on vendors to provide implementations. Passport, on the other hand, is a centralized service run by Microsoft, and is implemented in Microsoft’s Hotmail, Messenger and ISP services.

  • Federation and trust related
    • WS-Federation defines mechanisms that are used to “enable identity, account, attribute, authentication, and authorization federation across different trust realms”.
    • WS-Trust (Web Services Trust Language) is an extension to WS-Security that specifies how security tokens are exchanged and trust established.
  • Policy management standards
    • WS-Policy (Web Services Policy Framework) is a model for describing the policies of a Web service. It can be extended to describe service requirements, preferences, and capabilities.
    • WS-SecurityPolicy (Web Services Security Policy) is the WS-Policy Policy assertions that apply to WS-Security
  • The other security standards (the ones that couldn’t classify!)
    • WS-SecureConversation builds on WS-Security and defines how security contexts are establishing and shared, and how session keys can be derived from these contexts.
    • WS-Authorization will define how Web Services manage authorization data and policies
    • XrML (eXtensible rights Markup Language) is a language for expressing rights and conditions associated with digital content.
    • WS-Privacy will define how Web Services state and implement privacy practices.

Grid computing related standards

Some new standards that aim to integrate Web Services and Grid computing:

Leave a Comment

Time to move on

Well, its time to move my website from a paid hosting service to a free wordpress account. Why am I moving after all these years (almost 9 years now)?

Its hard to justify the effort of maintaining your own website, managing software issues- and the low payoff and the cost- and when free hosting services provide a better alternative. There are drawbacks off course- I can’t control the ads on this website, I don’t have the freedom to run whatever software I wish to run etc.; and content migration is a pain.

Oh well.

Leave a Comment