The Simple Messaging Framework  

The Simple Messaging Framework

Library Management Demo

Author: Naresh Bhatia (nbhatia@sapient.com)
Created: July 2003
Version: $Revision: 1.1 $ ($Author: nbhatia $ / $Date: 2003/07/21 03:30:50 $)

Introduction

The Library Management demo illustrates the use of the Simple Messaging Framework by implementing a Web service to reserve titles from a library. In addition it demonstrates the following:

  • Authentication mechanisms supported by the framework. (see Authentication)
  • Interoperability using a .NET client.
  • Implementation of a Web service using the REST paradigm.

This document describes the Library Management System and instructions to build and test it.

Library Management System

The Library Management System is a hypothetical application used for managing a library. One of its components, the Reservation Service, allows members to reserve titles from the library catalog. The ReservationService interface is shown below. Note the LmsContext object passed as the first parameter of each method. This object represents the context under which the method is called. Specifically, it contains a reference to the User object representing the user who made the request.

ReservationService API
package org.lms.reservationservice;
public interface ReservationService {

    /**
     * Finds titles that contain the specified keywords in their name field.
     *
     * @param ctx LmsContext for the call
     * @param keywords keywords to look for in the title field
     * @return A collection of TitleSummary objects that match the query
     * @throws ReservationServiceException if there is any error during this operation
     */
    Collection findTitles(LmsContext ctx, Collection keywords)
    throws ReservationServiceException;

    /**
     * Returns the TitleSummary for the specified ISBN.
     *
     * @param ctx LmsContext for the call
     * @param isbn ISBN of the title
     * @return The TitleSummary of the specified ISBN
     * @throws ReservationServiceException if there is any error during this operation
     */
    TitleSummary getTitleSummary(LmsContext ctx, Isbn isbn)
    throws ReservationServiceException;

    /**
     * Reserves a copy of the title specified by the supplied ISBN.
     *
     * @param ctx LmsContext for the call
     * @param isbn ISBN of the title
     * @return The Reservation object if successful, null otherwise
     * @throws TitleUnavailableException if the title is not available for reservation
     * @throws ReservationServiceException if there is any error during this operation
     */
    Reservation reserveTitleCopy(LmsContext ctx, Isbn isbn)
    throws ReservationServiceException;

    /**
     * Returns a collection of Reservations made by the user.
     *
     * @param ctx LmsContext for the call
     * @return A collection of Reservation objects associated with this user.
     * @throws ReservationServiceException if there is any error during this operation
     */
    Collection getReservations(LmsContext ctx)
    throws ReservationServiceException;
}

The diagram below shows the business objects used in this API as well as their relationships. The library stocks many Titles (books, CDs, videos etc.). Each Title can have several copies - represented by the TitleCopy objects. Each TitleCopy has a unique identification. The library has many Members. Each Member can reserve many TitleCopies. The attributes of a reservation are represented by the Reservation object. When a Member picks up a reserved title a Loan object is created to track the loan.

The SOAP Solution

The Library Management System exposes the ReservationService API as a Web service using SOAP. It also provides a Java client and a .NET client to access this Web Service. Both clients demonstrate the use of HTTP authentication as well as SOAP header authentication to authenticate themselves to the Web service. (In a real application you will probably use only one of these approaches.)

The REST Solution

In addition to a SOAP implementation, the Library Management demo also provides a REST implementation. REST is the acronym for REpresentational State Transfer, a phrase coined by Roy Fielding (primary architect of HTTP and director of the Apache Software Foundation) in his dissertation. REST describes the Web's architectural style in a rigorous fashion. REST suggests that HTTP itself is sufficiently general to model any application domain. It organizes a distributed application into URI addressable resources. All the capabilities of the application are provided through the use of standard HTTP messages as described below:

  • GET to retrieve the resource identified by a URI
  • PUT to create or update a resource at a URI
  • POST to add a subordinate to the resource at a URI (this may return the URI of the subordinate)
  • DELETE to delete the resource at a URI

For more information on REST visit the RESTwiki. The REST design for each of the ReservationService methods is documented below.

Find Titles

Collection findTitles(LmsContext ctx, Collection keywords);

Use GET from a URI of the form /lms/search?keywords=???. This URI identifies a resource which is the collection of TitleSummaries containing the specified keywords. This URI can be bookmarked, passed between friends, etc., and it will mean the same thing to everybody. The example below gets the TitleSummaries containing the keywords "graphic" and "friend".

GET /lms/search?keywords=graphic+friend

Get Title Summary

TitleSummary getTitleSummary(LmsContext ctx, Isbn isbn);

Use GET from a URI of the form /lms/title-summaries/<isbn>. This URI identifies a resource which is the TitleSummary of the specified ISBN. The example below gets the TitleSummary for ISBN 0-13-079666-2.

GET /lms/title-summaries/0-13-079666-2

Reserve TitleCopy

Reservation reserveTitleCopy(LmsContext ctx, Isbn isbn);

Use POST to the URI /lms/users/<username>/reservations. The action performed by this POST results in a reservation that can be identified by the URI /lms/users/<username>/reservations /<reservation-id>. Hence this post returns a status of 201 (Created). The response contains the Reservation entity as well as a Location header. The example below reserves a copy of the title with ISBN 0-13-079666-2.

POST /lms/users/johndoe/reservations
Parameter: isbn=0-13-079666-2

Get Reservations

Collection getReservations(LmsContext ctx);

Use GET from a URI of the form /lms/users/<username>/reservations. This URI identifies a resource which is the collection of all reservations made by the user. The example below gets the reservations made by johndoe.

GET /lms/users/johndoe/reservations

Build the Application

The Library Management System demo is located at smfw/samples/LibraryManagementSystem. We will refer to this directory as the prj.dir.

  1. If you have not yet installed the Simple Messaging Framework, please do so by following the Installation Guide.
  2. The Library Management System requires Tomcat 4.1.24 or later. If you do not have Tomcat, please download it and install it on your machine.
  3. If you would like to access the Library Management System using a .NET client, please make sure that you have installed Microsoft Visual Studio .NET.
  4. Edit the file prj.dir/ant.developer.properties to make sure it has the correct directory paths for your environment. If you have installed your libraries at locations recommended by the Installation Guide, then you may need to edit only one path - the lib.dir.
  5. Open a command shell and change the current directory to prj.dir
  6. .
  7. Execute the following command to build the Library Management System:
    ant build
  8. Execute the following command to build the Javadocs:
    ant javadoc

Test the SOAP Solution

  1. Execute the following command to start the Library Management System in Tomcat:
    ant start-soap-server
  2. Open a Web browser and point it to http://localhost:5001/lms
  3. Click on the ReservationService link to see the WSDL.
  4. You will be asked to authenticate yourself. Enter johndoe as your username as well as the password. Now click OK. The Web browser will show the WSDL for the ReservationService.
  5. Now open another command shell and change the current directory to prj.dir
  6. .
  7. Execute the following command to start the Java Web service client:
    ant start-soap-client

If you see the following output the Web service is working as expected.

[java] Finding titles with keywords [graphic, friend]...

[java] Received response of type org.lms.message.TitleSummariesMessage
[java] <?xml version="1.0" encoding='UTF-8'?>

[java] <message xsi:type="TitleSummariesMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-13-079666-2</isbn>
[java]       <name>Graphic Java (volume 1)</name>
[java]       <author>David M. Geary</author>
[java]       <publisher>Sun Microsystems, Inc.</publisher>
[java]       <year-published>1999</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>2</available>
[java]       <reserved>1</reserved>
[java]       <loaned>1</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-13-079667-0</isbn>
[java]       <name>Graphic Java (volume 2)</name>
[java]       <author>David M. Geary</author>
[java]       <publisher>Sun Microsystems, Inc.</publisher>
[java]       <year-published>1999</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>2</available>
[java]       <reserved>0</reserved>
[java]       <loaned>0</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-671-72365-0</isbn>
[java]       <name>How to Win Friends & Influence People</name>
[java]       <author>Dale Carnegie</author>
[java]       <publisher>Pocket Books</publisher>
[java]       <year-published>1981</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>1</available>
[java]       <reserved>0</reserved>
[java]       <loaned>0</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java] </message>

[java] Reserving a copy of ISBN 0-13-079666-2...

[java] Received response of type org.lms.message.ReservationMessage
[java] <?xml version="1.0" encoding='UTF-8'?>

[java] <message xsi:type="ReservationMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <reservation>
[java]     <id>1000</id>
[java]     <username>johndoe</username>
[java]     <title-copy-id>1001</title-copy-id>
[java]     <expiration-date>2003-07-26</expiration-date>
[java]     <loan-id xsi:nil="true" />
[java]   </reservation>
[java] </message>

[java] Getting TitleSummary for ISBN 0-13-079666-2...

[java] Received response of type org.lms.message.TitleSummaryMessage
[java] <?xml version="1.0" encoding='UTF-8'?>

[java] <message xsi:type="TitleSummaryMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-13-079666-2</isbn>
[java]       <name>Graphic Java (volume 1)</name>
[java]       <author>David M. Geary</author>
[java]       <publisher>Sun Microsystems, Inc.</publisher>
[java]       <year-published>1999</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>1</available>
[java]       <reserved>2</reserved>
[java]       <loaned>1</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java] </message>

[java] Reserving two ISBNs using a composite message...

[java] Received response of type org.sape.smfw.message.CompositeMessage
[java] <?xml version="1.0" encoding='UTF-8'?>

[java] <message xsi:type="CompositeMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <message xsi:type="ReservationMessage">
[java]     <reservation>
[java]       <id>1001</id>
[java]       <username>johndoe</username>
[java]       <title-copy-id>1005</title-copy-id>
[java]       <expiration-date>2003-07-26</expiration-date>
[java]       <loan-id xsi:nil="true" />
[java]     </reservation>
[java]   </message>
[java]   <message xsi:type="ReservationMessage">
[java]     <reservation>
[java]       <id>1002</id>
[java]       <username>johndoe</username>
[java]       <title-copy-id>1009</title-copy-id>
[java]       <expiration-date>2003-07-26</expiration-date>
[java]       <loan-id xsi:nil="true" />
[java]     </reservation>
[java]   </message>
[java] </message>

[java] Getting all reservations made by me...

[java] Received response of type org.lms.message.ReservationsMessage
[java] <?xml version="1.0" encoding='UTF-8'?>

[java] <message xsi:type="ReservationsMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <reservation>
[java]     <id>1000</id>
[java]     <username>johndoe</username>
[java]     <title-copy-id>1001</title-copy-id>
[java]     <expiration-date>2003-07-26</expiration-date>
[java]     <loan-id xsi:nil="true" />
[java]   </reservation>
[java]   <reservation>
[java]     <id>1002</id>
[java]     <username>johndoe</username>
[java]     <title-copy-id>1009</title-copy-id>
[java]     <expiration-date>2003-07-26</expiration-date>
[java]     <loan-id xsi:nil="true" />
[java]   </reservation>
[java]   <reservation>
[java]     <id>1001</id>
[java]     <username>johndoe</username>
[java]     <title-copy-id>1005</title-copy-id>
[java]     <expiration-date>2003-07-26</expiration-date>
[java]     <loan-id xsi:nil="true" />
[java]   </reservation>
[java] </message>

Now let us test the .NET client.

  1. Stop the Library Management System started earlier by stopping Tomcat.
  2. Execute the following command to restart the Library Management System:
    ant start-soap-server
  3. Now open another command shell and change the current directory to prj.dir
  4. .
  5. Execute the following command to start the .NET Web service client:
    ant start-dot-net-soap-client

If you see the following output the .NET client is working as expected and is interoperating correctly with the Java Web service.

MessageService URL = http://localhost:5001/lms/services/ReservationService

Finding titles with keywords graphic, friend...
response=TitleSummariesMessage:
title=ISBN 0-13-079666-2 - Graphic Java (volume 1):
  author(s)=David M. Geary,
  publisher=Sun Microsystems, Inc.,
  yearPublished=1999,
  numAvailable=2, numReserved=1, numLoaned=1
title=ISBN 0-13-079667-0 - Graphic Java (volume 2):
  author(s)=David M. Geary,
  publisher=Sun Microsystems, Inc.,
  yearPublished=1999,
  numAvailable=2, numReserved=0, numLoaned=0
title=ISBN 0-671-72365-0 - How to Win Friends & Influence People:
  author(s)=Dale Carnegie,
  publisher=PocketBooks,
  yearPublished=1981,
  numAvailable=1, numReserved=0, numLoaned=0

Reserving a copy of ISBN 0-13-079666-2...
response=ReservationMessage:
  id=1000, username=johndoe, titleCopyId=1001,
  expirationDate=07/26/03 12:00:00 AM, loanId=null

Getting TitleSummary for ISBN 0-13-079666-2...
response=TitleSummariesMessage:
title=ISBN 0-13-079666-2 - Graphic Java (volume 1):
  author(s)=David M. Geary,
  publisher=Sun Microsystems, Inc.,
  yearPublished=1999,
  numAvailable=1, numReserved=2, numLoaned=1

Reserving two ISBNs using a composite message...
response=CompositeMessage:
ReservationMessage:
  id=1001, username=johndoe, titleCopyId=1005,
  expirationDate=07/26/03 12:00:00 AM, loanId=null
ReservationMessage:
  id=1002, username=johndoe, titleCopyId=1009,
  expirationDate=07/26/03 12:00:00 AM, loanId=null

Getting all reservations made by me...
response=ReservationsMessage:
id=1000, username=johndoe, titleCopyId=1001, expirationDate=07/26/03 12:00:00 AM, loanId=null
id=1002, username=johndoe, titleCopyId=1009, expirationDate=07/26/03 12:00:00 AM, loanId=null
id=1001, username=johndoe, titleCopyId=1005, expirationDate=07/26/03 12:00:00 AM, loanId=null

Test the REST Solution

  1. Execute the following command to start the REST server in Tomcat:
    ant start-rest-server
  2. Now open another command shell and change the current directory to prj.dir
  3. .
  4. Execute the following command to start the REST client:
    ant start-rest-client

If you see the following output the REST Web service is working as expected.

[java] Finding titles with keywords [graphic, friend]...

[java] Received response of type org.lms.message.TitleSummariesMessage
[java] HTTP statusCode=200
[java] <?xml version="1.0" encoding='UTF-8'?>
[java] <message xsi:type="TitleSummariesMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-13-079666-2</isbn>
[java]       <name>Graphic Java (volume 1)</name>
[java]       <author>David M. Geary</author>
[java]       <publisher>Sun Microsystems, Inc.</publisher>
[java]       <year-published>1999</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>2</available>
[java]       <reserved>1</reserved>
[java]       <loaned>1</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-13-079667-0</isbn>
[java]       <name>Graphic Java (volume 2)</name>
[java]       <author>David M. Geary</author>
[java]       <publisher>Sun Microsystems, Inc.</publisher>
[java]       <year-published>1999</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>2</available>
[java]       <reserved>0</reserved>
[java]       <loaned>0</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-671-72365-0</isbn>
[java]       <name>How to Win Friends & Influence People</name>
[java]       <author>Dale Carnegie</author>
[java]       <publisher>Pocket Books</publisher>
[java]       <year-published>1981</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>1</available>
[java]       <reserved>0</reserved>
[java]       <loaned>0</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java] </message>

[java] Reserving a copy of ISBN 0-13-079666-2...

[java] Location header=Location: http://localhost:5001/lms/users/johndoe/reservations/1000
[java] Received response of type org.lms.message.ReservationMessage
[java] HTTP statusCode=201
[java] <?xml version="1.0" encoding='UTF-8'?>
[java] <message xsi:type="ReservationMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <reservation>
[java]     <id>1000</id>
[java]     <username>johndoe</username>
[java]     <title-copy-id>1001</title-copy-id>
[java]     <expiration-date>2003-07-26</expiration-date>
[java]     <loan-id xsi:nil="true" />
[java]   </reservation>
[java] </message>

[java] Getting TitleSummary for ISBN 0-13-079666-2...

[java] Received response of type org.lms.message.TitleSummaryMessage
[java] HTTP statusCode=200
[java] <?xml version="1.0" encoding='UTF-8'?>
[java] <message xsi:type="TitleSummaryMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <title-summary>
[java]     <title>
[java]       <isbn>0-13-079666-2</isbn>
[java]       <name>Graphic Java (volume 1)</name>
[java]       <author>David M. Geary</author>
[java]       <publisher>Sun Microsystems, Inc.</publisher>
[java]       <year-published>1999</year-published>
[java]     </title>
[java]     <title-inventory>
[java]       <available>1</available>
[java]       <reserved>2</reserved>
[java]       <loaned>1</loaned>
[java]     </title-inventory>
[java]   </title-summary>
[java] </message>

[java] Getting all reservations made by me...

[java] Received response of type org.lms.message.ReservationsMessage
[java] HTTP statusCode=200
[java] <?xml version="1.0" encoding='UTF-8'?>
[java] <message xsi:type="ReservationsMessage"
[java]     xmlns="http://www.lms.org/reservation-service"
[java]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[java]   <reservation>
[java]     <id>1000</id>
[java]     <username>johndoe</username>
[java]     <title-copy-id>1001</title-copy-id>
[java]     <expiration-date>2003-07-26</expiration-date>
[java]     <loan-id xsi:nil="true" />
[java]   </reservation>
[java] </message>

Copyright © 2003, Sapient Corporation