Skip to main content

skip to main content

developerWorks  >  SOA and Web services | WebSphere  >

Advertise Web services with Atom 1.0

developerWorks
Document options

Document options requiring JavaScript are not displayed

Sample code


New site feature

Check out our new article design and features. Tell us what you think.


Rate this page

Help us improve this content


Level: Intermediate

James Snell (jasnell@us.ibm.com), Software Engineer, IBM

07 Oct 2005

Advertise Web services using the new Atom 1.0 Syndication Format combined with the Web Services Addressing specification.

In November of 2001, IBM and Microsoft jointly published a draft of the Web Services Inspection Language (see Resources). Billed as "an XML format for assisting in the inspection of a site for available [Web] services," the fundamental intent of the specification was to provide a simple means of discovering when new services had been made available at a particular endpoint location. Unfortunately, while a few implementations of the specification did emerge in a few products, use of WS-Inspection never really took off. The specification has remained untouched and essentially forgotten since its publication.

Since that time, however, the need for a simple means of discovering when new Web services are available has not diminished, and work has continued in other areas. The W3C Web Services Addressing Working Group, for example, has been working to develop the means of addressing and referencing Web services endpoints. Unfortunately, neither the WS-Addressing specifications nor the related WS-* specifications being developed under the auspices of the W3C and OASIS organizations address the fundamental problem of providing a simple means of notifying clients when new Web services have become available.

Enter Atom 1.0. Over the course of the past year, the IETF Atom Publishing Format and Protocol Working Group has been working to define a standard XML format designed, in part, to allow clients to receive notification of when Web-based resources have been created or modified. Originally targeted at the syndication of Weblog and news content, the Atom Syndication Format is capable of serving as a means for distributing any arbitrary data format.

In the discussion that follows, I introduce and demonstrate the combined use of the Atom 1.0 and Web Services Addressing 1.0 specifications as a functional replacement for the now defunct WS-Inspection. A basic understanding of both the Atom and WS-Addressing specifications is assumed and it is recommended that you have a copy of both specifications handy as a reference as you continue reading. (See Resources for links to the specifications.)

A note on the code accompanying this article: The example is based on the Web services run-time embedded in IBM WebSphere® Application Server V6.0 (Application Server). While the concepts are easily adapted to other Web services run-times, if you wish to run the code, you will need to install Application Server. See the Resources section for a link to a trial version that you can download at no charge.

The approach

The sample code uses a Java™ servlet to generate an Atom 1.0 document (Listing 1) containing one entry for each Web service that has been deployed to the Application Server environment. Whenever a new Web service is deployed, a new entry is added to the Atom feed. By periodically polling the feed for new entries, clients can detect new or revised services.

In order to provide clients all of the information they need to access new service endpoints, each of the entries in the feed will contain a WS-Addressing Endpoint Reference that describes the endpoint.


Listing 1. An Atom+WS-Addressing feed

<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en" 
      xmlns="http://www.w3.org/2005/Atom"
      xmlns:fh="http://purl.org/syndication/history/1.0">
  <id>http://localhost:9085/wsatom/services.atom</id>
  <title>Web Services on localhost</title>
  <fh:incremental>false</fh:incremental>
  <updated>2005-08-23T23:00:35Z</updated>
  <link href="http://localhost:9085/wsatom/services.atom" 
        rel="self" 
        type="application/atom+xml"/>
  <author>
    <name>WebSphere</name>
    <uri>http://localhost:9085/wsatom</uri>
  </author>
  <entry>
    <id>tag:localhost,2005:/services/HelloWorld</id>
    <title>HelloWorld</title>
    <summary>Service 'HelloWorld' is available at 
http://localhost:9085/wsatom/services/HelloWorld</summary>
    <link href="http://localhost:9085/wsatom/services/HelloWorld" 
          rel="alternate"
          title="Service Endpoint"/>
    <link 
          href="http://localhost:9085/wsatom/services/HelloWorld?wsdl" 
          rel="alternate"
          title="WSDL" 
          type="application/wsdl+xml"/>
    <updated>2005-08-23T23:00:35Z</updated>
    <content type="application/xml">
      <EndpointReference 
        xmlns="http://www.w3.org/2005/08/addressing">
       <Address>http://localhost:9085/wsatom/services/HelloWorld
</Address>
      </EndpointReference>
    </content>
  </entry>
</feed>

Before I discuss how this feed is generated, I should point out that the Atom document generated by the servlet is always a complete set of the services available on the server. If a particular entry for a service drops off of the feed, it means that the service is no longer deployed on the server. Further, no significance is given to the order in which the services appear in the feed -- new services could appear at any position in the collection.



Back to top


Access the list of deployed services

The Web services run-time embedded in Application Server has been implemented around the Web Services for J2EE version 1.0 specification (referred to as JSR-109 -- see Resources) that defines the programming and deployment model for Web services in enterprise Java environments. The deployment model for JSR-109 is based on a declarative approach centered around a configuration file called webservices.xml.

According to the JSR-109 specification, webservices.xml "defines the set of Web services that are to be deployed in a Web services for J2EE enabled container." This translates roughly into "the webservices.xml file is where you need to look for the list of services that you are going to advertise in the Atom feed."

In a typical scenario, the webservices.xml file can be found most often in the /WEB-INF directory of a standard J2EE Web application. However, it is possible to find multiple webservices.xml files located throughout a Web application's classpath. Listing 2 shows the webservices.xml deployment descriptor for the sample application.


Listing 2. webservices.xml

<?xml version="1.0" encoding="UTF-8"?>
<webservices 
  xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  version="1.1" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd">
  <webservice-description>
    <webservice-description-name>HelloWorldService
    </webservice-description-name>
    <wsdl-file>WEB-INF/wsdl/HelloWorld.wsdl
    </wsdl-file>
    <jaxrpc-mapping-file>WEB-INF/HelloWorld_mapping.xml
    </jaxrpc-mapping-file>
    <port-component>
      <port-component-name>HelloWorld
      </port-component-name>
      <wsdl-port 
        xmlns:pfx="http://example.com">pfx:HelloWorld
        </wsdl-port>
      <service-endpoint-interface>com.example.HelloWorld
      </service-endpoint-interface>
      <service-impl-bean>
        <servlet-link>com_example_HelloWorld
        </servlet-link>
      </service-impl-bean>
    </port-component>
  </webservice-description>
</webservices>

The webservices.xml format consists of a top-level <webservices> element containing any number of child <webservice-description> elements -- one for each Web service that has been deployed. The contents of the <webservice-description> element specifies:

  • The name of services
  • The URL of the Web Services Description Language (WSDL) document describing the service
  • The mapping file that is used to associate native Java types with the appropriate XML representation
  • A binding of the service to a specific Java implementation

Of this information, you should be primarily concerned with just the service name and the WSDL.

The process that will be implemented is quite simple:

  1. Parse all available webservices.xml files.
  2. For each webservice-description found, create a WS-Addressing Endpoint Reference for the service.
  3. For each Endpoint Reference, create an Atom Entry.
  4. Add each Atom Entry to the Atom feed.


Back to top


Generate the Atom feed

All of the work for generating the Atom feed has been isolated to a single HTTP Servlet, outlined in Listings 3-6.


Listing 3. AtomServlet.java

package com.example.atom;

...

public class AtomServlet 
  extends HttpServlet 
  implements Servlet {

  ...

The first task -- handled by the init function shown in Listing 4 -- is the discovery of all available webservices.xml files. By default, check first in the Web application's WEB-INF directory. The JSR-109 deployment descriptors can also be found at various locations in a Web application's classpath,. In the sample implementation, searching the classpath for services is disabled by default.


Listing 4. Finding webservices.xml

  public void init(
    ServletConfig config) 
      throws ServletException {
        super.init(config);
        try {
          webservicesdocs = new ArrayList();
          File webservices = 
            new File(
              getServletContext().getRealPath(
                "WEB-INF/webservices.xml"));
          DocumentBuilderFactory dbf = 
            DocumentBuilderFactory.newInstance();
          dbf.setValidating(false);
          dbf.setNamespaceAware(true);
          documentBuilder = dbf.newDocumentBuilder();                    
          Document webservicesdoc = 
            documentBuilder.parse(webservices);
          webservicesdocs.add(webservicesdoc);
          if (INCLUDE_CLASSPATH) {
            Enumeration enum = 
              Thread.currentThread().
                getContextClassLoader().getResources(
                  "META-INF/webservices.xml");
            for (;enum.hasMoreElements();) {
              try {
               URL url = (URL)enum.nextElement();
               documentBuilder = dbf.newDocumentBuilder();
               Document doc = documentBuilder.parse(url.openStream());
               webservicesdocs.add(doc);
              } catch (Exception e) {}
            }
          }
          lastmodified = Calendar.getInstance();
          lastmodified.setTimeInMillis(webservices.lastModified());
        } catch (Exception e) {}  }
  ...

Once the set of webservices.xml deployment descriptors have been discovered and parsed, you are ready to serve up requests for the Atom feed. The process -- shown in Listing 5 -- is simple: If the webservices.xml document has been modified, the Atom document containing the complete current set of Endpoint References is generated and returned to the client.


Listing 5. Getting the Atom feed

protected void doGet(
    HttpServletRequest request, 
    HttpServletResponse response) 
      throws ServletException, 
             IOException {
      String modsince = 
        request.getHeader("If-Modified-Since");
      String lastmod = 
        httpdateformat(lastmodified);
      if (modsince != null &&
          modsince.equals(lastmod)) {
        response.setStatus(
          HttpServletResponse.SC_NOT_MODIFIED);
      } else {
        response.setContentType("application/atom+xml");
        response.setCharacterEncoding("utf-8");
        response.setHeader(
          "Last-Modified", 
          httpdateformat(lastmodified));
        Document doc = getAtom(request);
        OutputFormat of = new OutputFormat(doc);
        of.setOmitComments(true);
        of.setOmitDocumentType(true);
        of.setOmitXMLDeclaration(false);
        of.setEncoding("utf-8");
        of.setIndenting(false);
        of.setPreserveSpace(false);
        SerializerFactory factory = 
          SerializerFactory.getSerializerFactory(
            Method.XML);
        Serializer ser = 
          factory.makeSerializer(
            response.getWriter(), of);
        DOMSerializer domser = ser.asDOMSerializer();
        domser.serialize(doc);
      }
  }

Generating the Atom document (Listing 6) is a simple matter of iterating through all of the <webservice-description> elements found in the collection of webservice.xml files parsed when the servlet was initialized. A feed is created, and for each of the deployed services, an Atom entry is created.


Listing 6. Generating the Feed

  private Document getAtom(HttpServletRequest request) {
    Document feedDocument = documentBuilder.newDocument();
    Element feed = createFeed(feedDocument, request);
    NodeList nl = 
      webservicesdoc.getElementsByTagNameNS(
        WAS,"webservice-description");
    for (int n = 0; n < nl.getLength(); n++) {
      Element service = (Element) nl.item(n);
      feed.appendChild(
        createEntry(
          feedDocument, 
          service, 
          request));
    }
    return feedDocument;
  }
  
  private Element createFeed(
    Document doc, 
    HttpServletRequest request) {
      ...
  }
  
  private Element createEntry(
    Document doc, 
    Element service, 
    HttpServletRequest request) {
      ...
  }
  ...
}



Back to top


The end result

Once the servlet has been implemented, it is deployed to the Web application containing the Web services and given a URL mapping. An HTTP GET request to the servlet URL yields the generated Atom document (Listing 7).


Listing 7. http://localhost:9085/wsatom/services.atom

<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en" 
      xmlns="http://www.w3.org/2005/Atom"
      xmlns:fh="http://purl.org/syndication/history/1.0">
  <id>http://localhost:9085/wsatom/services.atom</id>
  <title>Web Services on localhost</title>
  <fh:incremental>false</fh:incremental>
  <updated>2005-08-23T23:00:35Z</updated>
  <link href="http://localhost:9085/wsatom/services.atom" 
        rel="self" 
        type="application/atom+xml"/>
  <author>
    <name>WebSphere</name>
    <uri>http://localhost:9085/wsatom</uri>
  </author>
  <entry>
    <id>tag:localhost,2005:/services/HelloWorld</id>
    <title>HelloWorld</title>
    <summary>Service 'HelloWorld' is available at 
    http://localhost:9085/wsatom/services/HelloWorld</summary>
    <link href="http://localhost:9085/wsatom/services/HelloWorld" 
          rel="alternate"
          title="Service Endpoint"/>
    <link 
      href="http://localhost:9085/wsatom/services/HelloWorld?wsdl" 
          rel="alternate"
          title="WSDL" 
          type="application/wsdl+xml"/>
    <updated>2005-08-23T23:00:35Z</updated>
    <content type="application/xml">
      <EndpointReference 
      xmlns="http://www.w3.org/2005/08/addressing">
      <Address>http://localhost:9085/wsatom/services/HelloWorld
</Address>
      </EndpointReference>
    </content>
  </entry>
</feed>

Once the Atom feed has been deployed, clients can subscribe to the feed using their favorite Atom 1.0-enabled feed readers, such as SharpReader, as shown in Figure 1. They can also programmatically access the feed, making use of the embedded WS-Addressing Endpoint Reference.


Figure 1. http://localhost:9085/wsatom/services.atom in SharpReader
http://localhost:9085/wsatom/services.atom in SharpReader


Back to top


Wrap-up

The example presented here was designed as a simple illustration of how Atom 1.0 can be combined with WS-Addressing to solve, in a simple way, the problem of discovering when new Web services are available without requiring the invention of yet-another-XML-format.




Back to top


Download

DescriptionNameSizeDownload method
Atom Web Services Sample Codews-atomwascode.zip18 KBHTTP
Information about download methods


Resources

Learn

Get products and technologies


About the author

Photo of James M Snell

James Snell is a member of IBM's Emerging Technologies Toolkit team. He has spent the past few years focusing on emerging Web services technologies and standards, and has been a contributor to the Atom 1.0 specification. He maintains a weblog focused on emerging technologies at http://www.ibm.com/developerworks/blogs/dw_blog.jspa?blog=351.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top