Getting started with WebSphere Service Registry and Repository

This article shows you two ways to populate WebSphere Service Registry and Repository (hereafter called Service Registry) with existing Web services information: using a sample Java application to load information from a spreadsheet (for customers who have maintained their Web service information in a spreadsheet before purchasing Service Registry), or using the Service Registry Service Discovery feature.

Martin Adams (martin.ed.adams@gmail.com), GUI Development Engineer , Ericsson Television Ltd.

Photo of Martin AdamsMartin Adams was a Software Developer on the Service Registry UI Test team at the IBM Software Lab in Hursley, United Kingdom. He graduated from University College Northampton with an honours degree in Internet Technologies and joined IBM UK as a graduate in 2004. He worked testing WebSphere Application Server transactions and Web services components, and in 2009, he joined the Service Registry Test team and worked in a variety of areas, including policy analytics and WebSphere Business Space. He specialises in UI testing and is a frequent mentor to other test teams looking to automate their UI testing. In 2010, Martin moved to a position as GUI Development Engineer with Ericsson Television Ltd. You can contact Martin at martin.ed.adams@gmail.com.



John Duffell (johnduffell@uk.ibm.com), Functional Tester, Service Registry team, IBM

Photo of John DuffellJohn Duffell is a Functional Tester on the Service Registry team at the IBM Software Lab in Hursley, United Kingdom. He joined IBM UK in his current role in 2006. Prior to joining IBM, he worked for Shepherd Construction in York as a Software Developer, where he developed construction management systems using Oracle. John graduated from the University of York in 2004 with an honours degree in Computer Science. You can contact John at johnduffell@uk.ibm.com.



Evan Jardine-Skinner (eskinner@uk.ibm.com), Software Engineer, IBM

Photo of Evan Jardine-SkinnerEvan Jardine-Skinner is a User Interface Software Developer on the Service Registry team at the IBM Software Lab in Hursley, United Kingdom. He joined IBM as a member of the Voice Systems Services team in 1998 and later used his services experiences to great effect in the development of Voice Response, mainly working on the ISDN signaling layers. He gained experience in porting IBM applications to new platforms working in the porting center, before his passion for usability drove him to join the Service Registry UI team in 2007. Evan graduated with an Honors degree in Computer Science from Bradford University, United Kingdom.



Bin Jia (binjia@uk.ibm.com), Software Developer, Service Registry team, IBM

Photo of Bin JiaBin Jia is a Software Developer on the Service Registry team at the IBM Software Lab in Hursley, United Kingdom. He was a lecturer at Tsinghua University in China in 1999. He joined the IBM China Research Lab as a research staff member in 2000, and then worked as a research associate in the Cambridge University Engineering Department from 2002 to 2004. In 2004, Bin joined IBM UK as a Software Developer. You can contact Bin at binjia@uk.ibm.com.



Manoj Pichirikat (manojp@in.ibm.com), Test Specialist, Service Registry team, IBM

Photo of Manoj Pichirikat Manoj Pichirikat is a Test Specialist on the Service Registry Test team in Bangalore, India. He joined IBM in 2000 and worked on the IBM Java Technology Centre Test team and the IBM Global Business Services (GBS) Asset Management Test team prior to his current role. You can contact Manoj at manojp@in.ibm.com.



Jerry Stevens (jerry_stevens@uk.ibm.com), Software Developer, Service Registry team, IBM

Photo of Jerry StevensJerry Stevens leads the WebSphere Service Registry and Repository (WSRR) Performance team at the IBM Software Lab in Hursley Park, United Kingdom. He joined IBM UK Global Services in 1997 as an IBM AIX Consultant, then transferred to WebSphere MQ Development and Performance Analysis in 2001, and to WSRR Development in 2009. He took on the WSRR Performance team role in 2011. Prior to joining IBM, Jerry worked for Shell UK as a Senior Systems Engineer, where he undertook a range of technical consultancy and development roles and worked with a variety of open systems platforms and architectures. He graduated from Exeter University with an Honours Degree in Mathematics.



15 December 2010

Also available in Chinese

Introduction

To harness the power of a Service Orientated Architecture (SOA), you need a central point of reference for all of your services -- a place to publish your service definitions, annotate them with metadata, and find them when you need them. If automation is on your list of priorities, then this central point of reference should also allow programmatic interrogation of the services and their associated metadata. Currently you may have this information spread across people and departments, perhaps with a single person responsible for it, or maybe you use a spreadsheet stored on a shared drive. Storing the data these ways makes it difficult to access and use in any automated process. If you can move this disparate data into IBM® WebSphere® Service Registry and Repository (hereafter called Service Registry), you can quickly start reaping the benefits of SOA.

Figure 1. Dewey Developer
Dewey Developer

Dewey Developer is writing a stock control application that lets users enter stock levels for items as they are delivered to the warehouse. He has been told that there is a service that can adjust the stock level in the database, but he doesn't know how to access it. He asks around and eventually finds someone that knows the endpoint Uniform Resource Locator (URL) and the format of the messages. He can now finish his application and roll it out across the enterprise. Soon after the rollout, the stock control application begins to malfunction and the stock levels cannot be updated, causing chaos when new stock arrives. What Dewey did not realize is that the service he is using is still in development and was not ready for deployed applications to use. If Dewey had obtained the service information from Service Registry, he would have been seen that the service was still in development, and all the disruption could have been avoided.

This article will guide you through two methods that will get you up and running with Service Registry. In the first method, existing Web services have been manually logged into a simple spreadsheet and need to be moved into Service Registry. The second method involves using Service Registry Service Discovery to automatically discover services that have been hosted on WebSphere Application Server. The article focuses on leveraging Service Registry features as quickly as possible.

Transposing services from a spreadsheet to Service Registry

A spreadsheet is a simple way to manage service information and associated metadata. This section shows you how to use a Comma Separated Values (CSV) version of a spreadsheet file and then use Java® to import the service documents into Service Registry using the Representational State Transfer (REST) API. By using Java to read the CSV file, you can use the HTTP POST method on the REST API to create the documents within Service Registry. The sample application in this article uses the same HTTP URLs that can be used by any Web browser. Here is a sample spreadsheet describing some basic information for a small group of services:

Table 1. Sample spreadsheet containing service metadata
Service IDNameNamespaceVersionDescriptionStatusDate in productionOwnerEndpoint URLDocumentation URL
SERV-001Pending Order Queryhttp://example.ibm.com1.0Returns the number of outstanding consumer ordersIn DevelopmentN/AOrder Processinghttp://localhost:9080/ProductionScenarioHttpRouter/services/PendingOrderQueryhttp://localhost:9080/docs/PendingOrderQuery.pdf
SERV-002Stock Reorderhttp://example.ibm.com1.2Creates a purchase order to reorder a stock itemIn Production24th March 2010Purchasinghttp://localhost:9080/ProductionScenarioHttpRouter/services/Reorderhttp://localhost:9080/docs/StockReorder.pdf
SERV-003Stock Adjustmenthttp://example.ibm.com1.0Modify the quantity of a stock itemIn DevelopmentN/AWarehousehttp://localhost:9080/ProductionScenarioHttpRouter/services/StockAdjustmenthttp://localhost:9080/docs/StockAdjustement.pdf
SERV-004Stock Queryhttp://example.ibm.com2.0Query the number in stock for a given itemIn Production12th February 2010Warehousehttp://localhost:9080/ProductionScenarioHttpRouter/services/StockQueryhttp://localhost:9080/docs/StockQuery.pdf

Exporting data as a CSV file

Export the spreadsheet to a CSV file, which will be used to import the services into Service Registry. Here is a sample CSV file based on the spreadsheet in Table 1:

Click to see code listing

Service ID,Name,Namespace,Version,Description,Status,Date in Production,Owner,Endpoint URL,Documentation URL

SERV-001,Pending Order Query,http://example.ibm.com,1.0,Returns the number of outstanding consumer orders,In Development,,
Order Processing,http://localhost:9080/ProductionScenarioHttpRouter/services/PendingOrderQuery,
http://localhost:9080/docs/PendingOrderQuery.pdf

SERV-002,Stock Reorder,http://example.ibm.com,1.2,Creates a purchase order to reorder a stock item,In Production,24/03/2010,
Purchasing,http://localhost:9080/ProductionScenarioHttpRouter/services/Reorder,http://localhost:9080/docs/StockReorder.pdf

SERV-003,Stock Adjustment,http://example.ibm.com,1.0,Modify the quantity of a stock item,In Development,,Warehouse,
http://localhost:9080/ProductionScenarioHttpRouter/services/StockAdjustment,http://localhost:9080/docs/StockAdjustement.pdf

SERV-004,Stock Query,http://example.ibm.com,2.0,Query the number in stock for a given item,In Production,12/02/2010,
Warehouse,http://localhost:9080/ProductionScenarioHttpRouter/services/StockQuery,http://localhost:9080/docs/StockQuery.pdf

If your CSV file is more complex and contains quoted content and nested commas within descriptions, see Known limitations of this sample application below.

Requirements of the sample application

  • Spreadsheet data is exported to a CSV file. (The sample application has a basic CSV parser. You can use a third-party CSV loader to make the import more robust.)
  • All the required Web Services Description Language (WSDL) and XML Schema Definition (XSD) documents are stored in a single folder.
  • The source code is modified to match the column headings of the spreadsheet being used.
  • Security is disabled on Service Registry. (The sample application demonstrates the simplicity of using the Service Registry REST API, but not the intricacies of encrypted HTTP communication. To connect to Service Registry with security enabled, you can use the sample application and apply common programming practices.)

How the sample application works

The sample application works by calling the command line and supplying the following parameters:

WSDLLoader   -csvFile <csvfile>   -wsdlPath <wsdlpath>  
    -hostname <hostname>    -port <port>

Where:

csvfile
Full path to the CSV file that will be imported
wsdlpath
Full path to a directory containing the WSDL and XSD documents
hostname
Hostname or IP address to the Service Registry service
port
Service Registry WC_defaulthost port. (WC_defaulthost port is the same port that the Service Registry Web UI is hosted on -- typically 9080 in a standalone environment.)

The sample application verifies that all parameters are supplied before instantiating an instance of the WSDLLoader class and calling the loadServices method:

Listing 1. Instantiating WSDLLoader and calling loadServices
// Initialize a new WSDL loader class with the command line parameters
WSDLLoader loader = new WSDLLoader(csvFile, wsdlPath, hostname, port);
   
// Load all the services, any exceptions throws will be returned back to the console
loader.loadServices();

The WSDLLoader.loadServices method is responsible for reading the services from the CSV file and processing each service entry to POST it into Service Registry:

Listing 2. The loadServices() method
/**
 *  Load all the services from the configured CSV file into Service Registry.
 * Depending on the format of the source CSV document, this method may require
 * modification to look up the relevant data. @throws Exception.  
 */
public void loadServices() throws Exception
{
   System.out.println("Loading WSDL Documents");

   // Read all the services from the CSV file into an ArrayList
   ArrayList<HashMap<String, String>> services = this.readCSV();

   // Add each services using the REST API
   Iterator<HashMap<String, String>> it = services.iterator();
   while(it.hasNext())
   {
      HashMap<String, String> service = it.next();

      // Get the name of the WSDL file from the CSV document
      String wsdlFileName = service.get("WSDL Filename");
   File wsdlFile = new File(this.wsdlPath, wsdlFileName);
/** 
 *  Build a URL with all the properties that we want.  Note the CSV column headers 
 *  must be exact when using generateProperty. Any number of properties can be added
 *  to the query string as they will be treated as custom properties on the document 
 *  when loaded into Service Registry. 
 */        
      String params = "name=" + 
         URLEncoder.encode(service.get("Name"), "UTF-8") +
         generateProperty(service, "description", "Description") +
         generateProperty(service, "version", "Version") +
         generateProperty(service, "Status", "Status") +
         generateProperty(service, "DateInProduction", "Date in Production") +
         generateProperty(service, "Owner", "Owner") +
         generateProperty(service, "EndpointURL", "Endpoint URL") +
         generateProperty(service, "DocumentationURL", "Documentation URL");

      // Generate master URL ready for POSTing the document to Service Registry.
      final String queryURL = "http://" + hostname + ":" + port + 
      "/WSRR/7.0/Content/WSDLDocument?" + params;

      // Load the document tree for this service entry.
      this.loadDocumentTree(queryURL, wsdlFile);
   }
}

When tailoring the sample application for a different spreadsheet, modify the list of parameters to build a query string matching the metadata columns in the spreadsheet. The queryURL String variable holds the full HTTP POST URL. The params variable is appended to the URL where a list of key/value attributes can be supplied. These attributes can be known properties on the document type WSDLDocument, such as name, description and version. Attributes that are not known are created as custom properties on the document when it is loaded in Service Registry. This allows for the flexibility to customize the metadata stored on the object depending on what information is in the spreadsheet.

The sample application has a basic method for reading the CSV file[1] that reads each line and parses the content. It assumes that the first line in the CSV file represents the column headers:

Listing 3. The readCSV() method to parse file content
/**
 * A basic method to read contents of CSV documents. Limited to cell values that are not
 *  encapsulated by quotes and do not contain nested commas in the cell values.
 * @return An ArrayList representing each row in the CSV document. The value of each 
 * entry is a HashMap that maps each column name to the cell value. The column names  
 * are determined by the first row in the CSV document.
 * @throws IOException
 */
private ArrayList<HashMap<String, String>> readCSV() throws IOException
{
   // Initialize the services ArrayList ready for reading from the CSV file
   ArrayList<HashMap<String, String>> services = 
      new ArrayList<HashMap<String,String>>();

      // Keep a simple array of the header fields from the first row
      String[] headers;

      // Read each line in the CSV file
      BufferedReader reader = new BufferedReader(new FileReader(this.csvFile));
      String line = reader.readLine();
      if(line != null)
      {
         // This is the first line, so assume it is the list of headers.  Perform a
         // basic split based on the comma to extract the header value.
         headers = line.split(",");

         // Read the remaining data lines
         while((line = reader.readLine()) != null)
         {
            // Perform a basic split based on the comma separation to extract the
            // cell values.
            String[] fields = line.split(",");

            HashMap<String, String> service = new HashMap<String, String>();

            // Add service to our hash map
            for(int i = 0, j = 0; i < headers.length && j < 
                fields.length; i++, j++)
            {
               service.put(headers[i], fields[j]);
            }
            services.add(service);
         }
      }

      return services;
}

After the metadata has been retrieved from the CSV file and prepared in a query URL, the document is ready for sending to Service Registry, which you do using the loadDocumenTree()method:

Listing 4. The loadDocumentTree() method
/**
 * POSTs a document file to the specified query URL. If the file fails to load due 
 * to a dependent file needing to load first, the method will recursively load all the 
 * dependants and try again.
 * @param queryURL Full path to the Service Registry POST URL including all the 
 * document properties 
 * @param sourceFile The file of the document to load
 * @throws Exception
 */
private void loadDocumentTree(String queryURL, File sourceFile) throws Exception
{
   // Attempt to load the document, but we may need to load any dependencies first.
   // If a document fails to load, the loadDocument method will throw a 
   // MustImportReferenceException. This method will keep retrying until all the
   // references have been loaded and the root document can finally be loaded.
   boolean retry = true;

   // Keep retrying until we load the document or an unexpected exception is thrown
   while(retry)
   {
      try
      {
         // Attempt to load the root document
         this.loadDocument(queryURL, sourceFile);

         // The document loaded successfully, so no need to keep retrying
         retry = false;
      }
      catch(MustImportReferenceException reference)
      {
         // We cannot load the root document yet as there is a referenced file
         // that needs to be loaded first
         File referenceFile = new File(this.wsdlPath, reference.getFilename());
         String name = referenceFile.getName();

         // See what type of document we need to load, for example WSDL or XSD
         String extension = name.substring(name.lastIndexOf(".") + 1);
         String type = null;

         if(extension.equalsIgnoreCase("wsdl"))
         {
            type = "WSDLDocument";
         }
         else if(extension.equalsIgnoreCase("xsd"))
         {
            type = "XSDDocument";
         }
         else
         {
            throw new Exception("Unsupported type " + extension + 
               " when loading referenced file " + reference.getFilename());
         }

         // Load the referenced document using the loadDocumentTree so that recursive 
         // references can be loaded also
         String referenceQueryURL = "http://" + this.hostname + ":" + this.port + 
         "/WSRR/7.0/Content/" +
         type + "?name=" + URLEncoder.encode(name, "UTF-8");

         this.loadDocumentTree(referenceQueryURL, referenceFile);
      }
   }
}

While it is possible to simply POST the WSDL document to Service Registry, it may fail because there could be any number of nested imports to additional WSDL or XSD documents. The solution to this problem without needing to identify the dependencies up front is to attempt to load the WSDL document and parse the server error to determine if it indeed required another document to be loaded first. This technique is required only if the nested import URLs are relative to the source document, instead of being fully qualified URLs that Service Registry can retrieve.

The loadDocumenTreemethod tries to load the document until all dependencies have been loaded or until there is another type of error. It calls the loadDocumentmethod, which throws a MustImportReferenceExceptionif a nested dependency must be loaded first:

Listing 5. The loadDocument() method
/**
 * POSTs a document in to Service Registry
 * @param queryURL The full URL to POST the document to including all 
 * document metadata as query parameters
 * @param sourceFile The file to POST
 * @throws MustImportReferenceException
 * If the server throws an Error 500 with codes 
 * "<code>GSR1350E</code><message>GSR0008E"
 * then this exception is thrown with filename of document that must be loaded first.
 * @throws Exception
 */
private void loadDocument(String queryURL, File sourceFile) throws Exception
{
   // Open a connection to Service Registry
   URL url = new URL(queryURL);
   HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
   urlConnection.setRequestMethod("POST");
   urlConnection.setRequestProperty("Content-Type", "UTF-8");

   urlConnection.setDoInput(true);
   urlConnection.setDoOutput(true);
   urlConnection.setUseCaches(false);

   // Read the file contents and send it to Service Registry
   InputStream in = new FileInputStream(sourceFile);
   OutputStream out = urlConnection.getOutputStream();

   int c;
   while((c = in.read()) != -1)
   {
      out.write(c);
   }
   out.flush();

   // Read the response from the server
   BufferedReader reader = null;
   try
   {
      reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
      StringBuffer stringBuffer = new StringBuffer();
      String line = null;

      while(null != (line = reader.readLine()))
      {
         stringBuffer.append(line);
      }
      reader.close();

      // Check for a successful POST and the document has been created
      if(urlConnection.getResponseCode() == 201) // Created
      {
         System.out.println("Successfully created " + sourceFile.getName());
      }
      else
      {
         throw new Exception("Unable to create " + sourceFile.getName() + ": " + 
            stringBuffer.toString());
      }
   }
   catch(IOException ex)
   {
      // If we fail to read the response, check the error stream as this may include 
      // details of the required dependency that we need to handle

      // Attempt to read the error stream
      reader = new BufferedReader(new InputStreamReader(urlConnection.getErrorStream()));
      StringBuffer stringBuffer = new StringBuffer();
      String line = null;

      while(null != (line = reader.readLine()))
      {
         stringBuffer.append(line);
      }
      reader.close();

      if(urlConnection.getResponseCode() == 500)
      {
         // We have an error 500 exception, attempt to see if it is a GSR0008E exception
         // indicating that we must import a dependency first.
         String referencedFile = getReferencedFilename(stringBuffer.toString());

         // If the referenced file is null, it was a different error, so re-throw it, 
         // otherwise, prepare a MustImportReferenceException so the dependency can be
         // handled
         if(referencedFile != null)
         {
            throw new MustImportReferenceException(referencedFile);
         }
      }

      // Unknown cause of error, throw an exception with the details
      throw new Exception("Received unexpected response " + 
        urlConnection.getResponseCode() + 
           ": " + stringBuffer.toString());
   }
}

Known limitations of the sample application

This sample Java application demonstrates the simplicity of loading content in Service Registry and enriching it with additional metadata. Known limitations:

  • The CSV parser does not handle quotations around the cell values.
  • It only works when security is disabled.

Terminology

Metadata
"Data about data." In Service Registry, metadata refers to data associated with the objects created in it, such as owner, last modified date, and relationships with other objects.
Namespace
A container within the scope of which uniquely defined (named) items exist. A namespace cannot contain two items with the same name. For example, in programming languages, package names are used to address unique identifier requirements. In an XML document, namespaces are used to address identical named elements or attributes.
REST API
One of the API types supported by Service Registry apart from EJB APIs and Web services. REST is an architectural style for accessing and manipulating resources.
Uniform Resource Identifier (URI)
Used to identify a resource in a network in terms of its name and/or location.
Web Service Description Language (WSDL)
An abstract representation used to describe Web services in XML format.
XML Schema Definition (XSD)
A standard language or format used to describe the structure of an XML document.

Discovering services automatically using the Service Registry Service Discovery feature

Service Discovery is the simplest way to get up and running with Service Registry. It provides an accurate representation of your deployed services. This section shows you how to configure and run Service Discovery to pull in information from a production server, and how to explore the new services.

The example uses a production WebSphere Application Server running the sample application supplied with this article (ProductionScenario.ear). The server has administrative security disabled, although we also cover the situation with security enabled. A separate standalone server is installed with the default settings running Service Registry with the default profile loaded and active.

Configuring Service Discovery

A perspective is a view by the Service Registry UI for a given user login. It is defined by the profile currently active within Service Registry. There may be different perspectives, with the Basic and Governance Enablement profiles, including the Administrator and the Configuration perspectives. You can customize perspectives according to the needs of your organization. The default Configuration perspective described here is always available for administrative users, and is used for configuration purposes as described above.

  1. Open the Service Registry Web UI and log in as administrator. If you have a standalone application server, the URL will be something like http://localhost:9080/ServiceRegistry/ The port number may vary if you have more than one installation of WebSphere Application Server -- port numbers are specified during installation.
  2. Use the Perspective dropdown in the top right corner to switch to the Configuration perspective.
  3. Use the Active Profile dropdown and choose Service Discovery:
    Figure 2. Service discovery configuration
    Service discovery configuration
  4. Click ServiceDiscoveryConfiguration. It makes Service Registry aware of the application server so that it can determine what is running there.
  5. Replace the file shown with the one in the listing below. Fill in the host name, port number, and security details if appropriate:
Service Discovery configuration
<?xml version="1.0" encoding="UTF-8"?>
<service-discovery 
xmlns="http://www.ibm.com/xmlns/prod/serviceregistry/6/2/servicediscovery">
   <discovery-task name="WASDiscoveryTask">
      <discoverer type="WAS"/>
      <configuration>
         <instance name="production">
            <host></host>
            <port></port>
            <conn-type>SOAP</conn-type>
            <security-enabled></security-enabled>
            <username></username>
            <password></password>
         </instance>
      </configuration>
   </discovery-task>
</service-discovery>
  1. Click OK.

If your server is running with security enabled and is using a self-signed certificate, follow instructions in the information centre topic Connecting to a secured WebSphere Application Server environment.

Running Service Discovery

  1. Open a command prompt on the Service Registry server.
  2. Change to your Service Registry scripts directory <WSRR_INSTALL_LOCATION>/admin/scripts_cell:
    • On Windows®, enter cd c:\Program Files\IBM\WebSphere\AppServer\WSRR\admin\scripts_cell
    • On Linux®, use enter cd /opt/IBM/WebSphere/AppServer/WSRR/admin/scripts_cell
  3. Enter the command to kick off Service Discovery, substituting localhost if needed.
    • On Windows, enter c:\Program Files\IBM\WebSphere\AppServer\bin\wsadmin -f executeSchedulerTaskImmediate.jacl -cell localhostNode01Cell -node localhostNode01 -server server1 -taskname WASDiscoveryTask
    • On Linux, enter /opt/IBM/WebSphere/AppServer/bin/wsadmin.sh -f executeSchedulerTaskImmediate.jacl -cell localhostNode01Cell -node localhostNode01 -server server1 -taskname WASDiscoveryTask

Your services will be discovered and loaded into Service Registry. You can run service discovery multiple times without causing duplicate entries in Service Registry.

Figure 3. Running service discovery
Running service discovery

Exploring the new services

  1. Open the Service Registry Web UI and log in as an administrator. If you have a standalone application server, the URL will be something like http://localhost:9080/ServiceRegistry/.
  2. Use the Perspective drop down in the top right corner to switch to the Administrator perspective.
  3. Under Service Documents, click WSDL Documents:
    Figure 4. WSDL documents
    WSDL Documents
  4. You can see the four WSDL documents that are part of the production EAR file:
    Figure 5. Production EAR file
    Production EAR file
  5. To view the full documents, click the name or go into the graphical view.

Congratulations -- your services are now stored in Service Registry and are ready for use!

Looking up service information and details with REST

Now that your service information is in Service Registry, you can continue to use the Web UI to query, edit, and delete artifacts. You can also access Service Registry from one of three APIs, which means you can also run queries from bespoke applications. One of these APIs is the Representational State Transfer (REST) API.

The advantages of REST are that it is simple to use and easy to make queries from systems remote to the location where Service Registry is installed. A query may first be tested by using it from a browser and may then be used within a bespoke client application. Clients that use REST can be simple lightweight Java applications, which means that you can very quickly build and test custom queries and then deploy them across your organisation.

This section shows you how to use simple REST queries, both from an Web browser and from a lightweight Java application, to retrieve details of the services that were introduced earlier in this article. These examples use a standalone local server with security disabled, running on the default ports. You can change the port number and host name in the URL to suit your own server location.

Types of Service Registry queries

In a moment you will learn how to use REST queries directly from a browser or within a simple Java application. But first it is worthwhile to understand the different types of queries in Service Registry that the REST API can use:

  • Predefined persistent queries

    Are provided with Service Registry to enable you to easily issue frequently used queries. For example, the getAllWSDLDocuments query returns the attributes of all WSDL documents stored in the registry and can be invoked by going to the following URL in a Web browser:
    http://localhost:9080/WSRR/7.0/Metadata/XML/Query/getAllWSDLDocuments.
    The result will should show all WSDL documents in Service Registry.

    Because predefined persistent queries are built into Service Registry, they do not allow customisable and more complex search expressions to be used alongside them. That is where property and graph queries come in. For a full list of built-in queries, see Predefined persisted queries in the information centre. To add your own queries, see Creating content in the information centre.

  • Property queries

    Return a specified subset of information from a Service Registry object that matches a search expression given within the query. For example, a property query can be used to return a simple XML list of the owners of all Service Registry documents stored in the registry.

  • Graph queries

    Return all the properties of objects that match a specified search expression given to the query. They can also transverse the hierarchy of objects stored in Service Registry, which property queries cannot do. The use of graph queries with certain types of client other than REST offer an additional facility to return information from objects related to the one being queried. These queries can go to a specified depth down the relationship chain. For more information, see Alternative APIs below.

  • User-defined persistent queries

    A graph or property query written by a customer and then stored in the Service Registry configuration profile so that it can be efficiently reused.

  • Extending property and graph queries with xPath

    You can extend property and graph queries to have embedded query expressions written using a query language called xPath. For example, you can use an xPath expression in a property or graph query to return all WSDLs with a name beginning with "FRED." The XPath query language is a defined by the World Wide Web Consortium (W3C), and Service Registry implements a subset of it.

REST query expressions

Since you have now seen the types of queries available in Service Registry, turn your attention back to REST and how you might create and use some real property and graph queries. A REST query is made by specifying a URL that contains all the required parameters for the search. This URL is formed around a root URL of the form: http://hostname:port/WSRR/7.0

For example: http://localhost:8087/WSRR/7.0

You then append this URL with other URL elements to form a complete REST query URL. For example, to use the predefined persistent query getAllWSDLDocuments, the complete query string might be:
http://localhost:8087/WSRR/7.0/getAllWSDLDocuments.

Using Service Registry REST queries from a Web browser

This section shows you how to use REST queries from a Web browser, which is an easy way to interrogate Service Registry and to test specific queries before using them in a Java application.

Property query

The syntax of a property query is:
<ROOT-URL>/Metadata/XML/PropertyQuery?query=<XPathExpression>&p1=<param1>...

Property queries are used to return a specified selection of metadata. For example, the query:
http://localhost:9080/WSRR/7.0/Metadata/XML/PropertyQuery?query=/WSRR/WSDLDocument&p1=name

returns the names of all WSDL documents stored in the registry. With the samples used in this article, the query returns data as follows:

Figure 6. WSDL documents stored in the registry
WSDL documents stored in the registry

You can see the following information in the example query URL above:

  • it specifies the use of a PropertyQuery
  • p1=name is added on the end in order to request the name property

You can add as many properties as you need to the request list. For example, this URL returns the name, description, and version of all WSDL documents:

Click to see code listing

http://localhost:9080/WSRR/7.0/Metadata/XML/PropertyQuery?query=/WSRR/WSDLDocument&p1=name&p2=description&p3=version

You can use an xPath in a property query to refine the search. For example, to extract the names of all WSDLs whose file names end in Query.wsdl, use the following query statement:

Click to see code listing

http://localhost:9080/WSRR/7.0/Metadata/XML/PropertyQuery?query=/WSRR/WSDLDocument[matches(@name, '.*Query.wsdl')]&p1=name

With the example data used in this article, the query returns the following result in a browser:

Figure 7. Property query with an XPath expression
Property query with an XPath expression

Graph query

The syntax of a graph query is:
<ROOT-URL>/Metadata/XML/GraphQuery?query=<XPathExpression>

The URL indicates the use of a graph query. For example, the query:
http://localhost:9080/WSRR/7.0/Metadata/XML/GraphQuery?query=/WSRR/WSDLDocument[@name="StockQuery.wsdl"]

could be used to return the metadata stored in Service Registry that is associated with the WSDL file StockQuery.wsdl. A sample result of this query is shown below. If you get an error, check that your server is running and is listening on localhost, port 9080:

Figure 8. Graph query
Graph query

The URL http://localhost:9080/WSRR/7.0/Metadata/XML/GraphQuery?query=/WSRR/WSDLDocument[@name="StockQuery.wsdl"] is composed of several parts:

  • http://localhost:9080 is the location of the server, and is the same as the Web UI location.
  • GraphQuery specifies that all metadata about the objects is to be returned, rather than specific items.
  • /WSRR/WSDLDocument[@name="StockQuery.wsdl"] is the query expression, which you must specify as Service Registry XPath

You can modify the query expression to return different objects. The following query returns all WSDL service objects that have been shredded from documents:
http://localhost:9080/WSRR/7.0/Metadata/XML/GraphQuery?query=/WSRR/WSDLService

For more information on writing query expressions, see Searching and querying in the Service Registry information centre.

Retrieving content from services using REST

In addition to making queries about the metadata associated with objects in Service Registry, you can use the REST API to directly retrieve the content of an object, such as the contents of a WSDL document. In the graph query above, you can see that the WSDL document StockQuery.wsdl has been loaded into Service Registry and that this has been assigned a bsrURI of 1c85171c-2918-4846.8b8f.26b95a268f7e. Using this bsrURI value, you can make a REST call to retrieve the contents of the WSDL document. The REST call is made with a URI of the form:
<RootURL>/Content/<bsrURI>

For example:
http://localhost:9080/WSRR/7.0/Content/1c85171c-2918-4846.8b8f.26b95a268f7e

When this URI is entered into a browser, it will either display directly, or offer to save the contents of the WSDL locally, depending on the browser used.

Using Service Registry REST queries from within a Java application

As stated earlier, the big benefit of using the REST API is that in addition to interrogating the registry from a Web browser, you can make REST calls from a simple Java application. For example, having populated Service Registry, you may need a concise list of service names with the Service Registry bsrURIs and associated service endpoints. The next section shows you how to do generate this list using a Java application named testRESTQuery.java. This application just needs a Java compiler and SDK to build it.

Source code

The program works by making two types of property query with the REST interface. The first returns the service names known to Service Registry with their bsrURIs, and has the form: <RootURL>/Metadata/XML/PropertyQuery?query=~//WSDLService&p1=name&p2=bsrURI

Given the above query URL, the method doQuery() opens the URL and retrieves the response, which is an XML document that contains the service names and bsrURIs known to Service Registry. This data is then returned by the method as a StringBuffer. Here is the doQuery() method:

Listing 7. Example REST call from Java -- extracting all service names known to Service Registry
public StringBuffer doQuery(String aURL)
{
   StringBuffer stringBuffer = null;
   String line;
   try
   {
      URL url = new URL(aURL);
      URLConnection urlConnection = url.openConnection();

      BufferedReader reader = new BufferedReader(
         new InputStreamReader(urlConnection.getInputStream()));
      stringBuffer = new StringBuffer();

      while(null != (line = reader.readLine()))
         stringBuffer.append(line);
      reader.close();

   }
   catch (Exception e)
   {
      System.out.println("EXCEPTION: " + e.toString());
      e.printStackTrace();
   }
   return stringBuffer;

The Java application then calls the method processServices() to parse the XML data returned from the first query, from which it extracts all the service names with their bsrURIs and then for each service performs a second property query:

<RootURL>/Metadata/XML/PropertyQuery?query=/WSRR/WSDLService[@name='<ServiceName>']/ports/
 SOAPAddress&p1=location

The purpose of this query is to retrieve the location details for each identified service. For each service, the processServices() method assembles the correct query based on the second query URL above, and then calls the doQuery() method again to open the assembled URL and return the results of the search as a StringBuffer. This data is then parsed by the getEndPoint() method, which extracts the location details for the searched service. The processServiceNames() method then displays the service name and endpoint to the console. Here is the processServices() method:

Listing 8. Example REST call from Java - determining an individual service's location details
public void processServices(StringBuffer s)
{
   try
   {
      DocumentBuilder documentBuilder = 
         DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document contentDocument = 
         documentBuilder.parse(
            new InputSource(new StringReader(s.toString())));

      NodeList propertiesList = 
         contentDocument.getElementsByTagName("properties");


      for (int i=0; i < propertiesList.getLength(); i++)
      {
         Element properties = (Element) propertiesList.item(i);
         NodeList propertyList = properties.getElementsByTagName("property");

         String serviceName = null;
         String bsrURI = null;
         for (int j=0; j < propertyList.getLength(); j++)
         {
            Element property = (Element) propertyList.item(j);
            String propertyName = property.getAttribute("name");
            if (propertyName.equals("name"))
               serviceName = property.getAttribute("value");
            else if (propertyName.equals("bsrURI"))
               bsrURI = property.getAttribute("value");
         }

         if ((null != serviceName) && (null != bsrURI))
         {
            String queryURL = getRootURL() + 
            "/Metadata/XML/PropertyQuery?query=/WSRR/WSDLService"
            +"[@name='"
            + serviceName
            + "']/ports/SOAPAddress&p1=location";

            String endPoint = getEndPoint(doQuery(queryURL));
            System.out.println(
               serviceName + "(" + bsrURI + ")" + " => " + endPoint);
         }
      }

   } catch (Exception e)
   {
      System.out.println("EXCEPTION: " + e.toString());
      e.printStackTrace();
   }
}

The full source code of the application is attached to the article.

Building and running the test REST API query application

The test application is built using a standard Java SDK environment. No J2EE support or knowledge of Service Registry EAR files is required. You can compile the application by executing javac testRESTQuery.java, which produces the following output:

StockAdjustmentService(87d6e587-6af2-426b.9b75.00ec8c0075c8) => 
   http://localhost:9080/ProductionScenarioHttpRouter/services/StockAdjustment
StockQueryService(f9820af9-471c-4cee.a87d.9c9e6a9c7d9d) => 
   http://localhost:9080/ProductionScenarioHttpRouter/services/StockQuery
PendingOrderQueryService(d5861bd5-9e96-46e1.9984.e4a651e484fa) => 
   http://localhost:9080/ProductionScenarioHttpRouter/services/PendingOrderQuery
ReorderService(c74da2c7-e491-41cf.9dc1.ddbd5eddc1fa) => 
   http://localhost:9080/ProductionScenarioHttpRouter/services/Reorder

There are four services, displayed one per line with their Service Registry bsrURIs in brackets and the service endpoints. This example will not work with a secured server.

Alternative APIs

In this section you have seen the use of the REST interface for making queries on Service Registry data from within Web browsers and Java applications. There are two other types of interfaces that you can use to build Service Registry queries: the EJB client and the Web service interface. These interfaces require additional effort to set up and develop, so this article has focussed on REST. A key advantage of using these alternative interfaces is that graph queries can be extended to return information about all objects related to the one being searched, down to a specified level. This facility is not available from the REST API. For more information, see the Service Registry information centre.

Use of REST with JavaScript Object Notation (JSON)

The sample REST calls shown in this section have all returned XML data. REST calls made to Service Registry can also return JSON-formatted data, which has the advantage of being readily interpreted by Dojo (an open-source JavaScript toolkit), which is useful if you are developing a Dojo front-end to Service Registry. For more information, see Retrieving metadata in the Service Registry information centre.

Terminology

bsrURI
The bsrURI is an identifier which uniquely identifies an object in the Service Registry. To find out the bsrURI of an object, use the Service Registry UI to view the object and then check the bsrURI field under Additional properties. For example, if you were to find out the bsrURI of an organization, click View => Organization and then expand the additional properties section.
Dojo
An open-source JavaScript toolkit.
JSON
A lightweight data-interchange format based on the object-literal notation of JavaScript. JSON is programming-language neutral but uses conventions from languages that include C, C++, C#, Java, JavaScript, Perl, and Python.
Property queries
A query that returns a subset of the properties of an object (the target object or the query object itself) depending on the query expression used. For more details, see the information centre.
Service end point
A string used to identify and access a service using the protocols, data format, and location of the service.
XPATH

A syntax or expression language used to refer to parts of an XML document. From the point of view of Service Registry, XPATH is used to query objects based on object type hierarchy. For example: /WSRR/WSDLDocument.

For details on the XPath specification, see XML Path Language (XPath) V1.0. W3C Recommendation.

For details on the IBM XPath implementation within Service Registry, see Searching and querying in the Service Registry information centre.

Annotation

Annotating services loaded into Service Registry lets you associate services with various kinds of information. You can add information for many user-defined categories, including versions, organization names, attached documents, and more. This section shows you how to annotate your services.

Managing different versions of Web services

Assume you have loaded a WSDL file named StockQuery.wsdl with a version of 1.0:

Figure 9. A WSDL is loaded
A WSDL is loaded

You then load a new WSDL file with the same file name, but version 2.0:

Figure 10. A WSDL is loaded with a different version
A WSDL is loaded with a different version

You can then use the version numbers to differentiate between the two WSDLs. To retrieve a specific version of the WDSL, run a query using Query Wizard and specify the WSDL file name and version number. The result of running this query in the Query Wizard specifying file name = StockQuery.wsdl and version = 20 is shown below:

Figure 11. A WSDL query result
A WSDL query result

Using classifications to organize your services

Service Registry supports the classification of services to enable you to tag them for use in queries. Multiple classifications can be applied to each object. Classification systems are defined to Service Registry using Web Ontology Language (OWL) files. OWL is a family of XML-based languages endorsed by the World Wide Web Consortium that is used to build conceptual models of Web related information based on types, properties, and relationships. In the example below, a service has been classified as belonging to a specific organization by loading an organization classification system named Organizations via an OWL file. The system contains three departments:

Figure 12. A classification is loaded
A classification is loaded

You can add one of the Organization classifications to version 1.0 of the StockQuery.wsdl files that you loaded earlier. In the example, add the Mutual Funds Department classification to it:

Figure 13. A classification is added to a WSDL
A classification is added to a WSDL

After the classification has been added, you can use it in the Query Wizard to enhance your queries. If you query for all entities classified by Mutual Funds Department you will see:

Figure 14. A classification query result
A classification query result

For information on adding new classifications to Service Registry and creating your own classification system, see Creating a classification system in the Service Registry information centre.

Documenting your services

Services loaded within Service Registry can be annotated with human readable documentation, enabling you to maintain service definitions and their documentation in one place. The example below shows how a WSDL that has been loaded into Service Registry has documentation attached to it by creating a relationship from the WSDL definition to the document. In the relationships section of the image below, you can see the new relationship named Documentation that points to stockProfiles.doc. Service Registry enables users to easily download and use this documentation.

Figure 15. A WSDL with Word document
A WSDL with Word document

Advanced capabilities of Service Registry: Service governance

An important Service Registry capability is service governance, so that you can control which services are available for use and who is using them. Here is a scenario that illustrates the value of service governance with Service Registry:

Scenario: Service governance

Tom works in the Logistics and Purchasing department and develops the StockQuery service, which is used by several of his applications. He deploys this service on the desktop machine that he uses:

Figure 16. StockQuery service within Logistics and Purchasing department
StockQuery service within Logistics and Purchasing department

Tom finds that the requirements on his application have increased because of new responsibilities he has taken on and the expansion of his department. He identifies other services -- PendingOrderQueryService , ReorderService, and StockAdjustmentService -- that his application requires in addition to the original StockQueryService. Tom develops, tests, and deploys these new services on his machine. Co-workers in his department learn of Tom's services and ask him to show them how to use these services. Tom agrees.

Figure 17. StockQuery, PendingOrderQuery, Reorder, and Stock Adjustment services within Logistics and Purchasing department
StockQuery, PendingOrderQuery, Reorder, and Stock Adjustment services within Logistics and Purchasing department

The services work well within Tom's department, and soon, various employees from other departments start using these services because of lack of time to develop their own applications, and lack of funding to purchase commercial applications from outside the company. The employees from other departments and their managers are happy using the new services in their applications, and Tom's manager is glad to hear how Tom is helping the entire organization save money through the growing use of his effective services:

Figure 18. StockQuery, PendingOrderQuery, Reorder, and Stock Adjustment services developed by Logistics and Purchasing department and used by other departments
StockQuery, PendingOrderQuery, Reorder, and Stock Adjustment services developed by Logistics and Purchase department and used by other departments

Tom's desktop starts getting slower as the days pass, but his department doesn't have money for upgrades, so he tunes it using some tips he finds on the Internet. That helps a little but is hardly a solution, because the organization keeps growing, resulting in increasingly complex applications and increasing loads on his services. Tom's own application starts slowing down, but he feels helpless because so many users of his services are relying on his machine, and he starts getting formal requests routed through his manager to fix problems and modify his services to suit new requirements. Instead of doing his normal full-time department work, he starts spending more and more time fixing bugs and trying to accommodate requests for enhancements to the services he has created.

Figure 19. Increased external and internal load on StockQuery, PendingOrderQuery, Reorder, and Stock Adjustment services
Increased external and internal load on StockQuery, PendingOrderQuery, Reorder, and Stock Adjustment services

Disaster strikes as it usually does, unexpectedly

One Friday evening, Tom leaves on a week-long wilderness backpacking trip, leaving his mobile phone at home because where he's going, it doesn't work. The next day on Saturday, an office power outage causes Tom's desktop to go down and with it, all of the other applications that depend on it. E-mail complaints start flowing in, and they are answered with an out-of-office note telling the recipients to contact Tom's manager in his absence. Tom's manager then gets a flood of e-mails, some of which are escalated, and the situation grows steadily worse as customers are increasingly affected. Customer orders are ignored or unfilled, orders get cancelled, customers are angry, and worst of all, no one knows what to do.

Service Registry and the Enterprise Service Bus could give this story a happy ending

Lets rewind and go back to the middle of the story, when Tom's desktop starts slowing down, and he starts getting requests to fix problems in his services and modify them to suit new requirements. But this time, instead of dealing with these challenges on his own, Tom goes to his manager and tells him that managing these services on his own is neither smart nor sustainable in the long run, and they need SOA governance. Tom and his manager find out that the organization has already started investing in SOA in order to integrate their legacy systems with new services across the enterprise. They learn that the company has set up a SOA Centre of Excellence and they get in touch with that team.

Tom, his manager, and the SOA Centre of Excellence team meet and to discuss the situation, and decide to deploy and manage the services on machines in the company data centre. Tom sends out a note to everyone they know who is using their services, educating them on the changes as well as the benefits. The company's SOA Governance Board oversees the creation of Documents of Understanding as well as Service Level Agreements, which document user requirements and are signed by users and by the team that maintains the services. These documents are then uploaded into Service Registry. Users now access services via an ESB, which queries Service Registry and redirects requests to the appropriate services based on mediation logic. Whenever they receive a request to create a new service, the SOA Centre of Excellence team uses Service Registry to search existing services to ascertain whether an existing service or an enhancement to an existing service will meet the requirement, or whether a new service is needed. They also plan the most efficient way to migrate services while minimizing disruptions to users.

A dedicated support team in the data centre plans and implements disaster recovery and maintenance activities for servers in case of events such as earthquakes, floods, and power failures. A performance analyst makes performance measurements on the infrastructure and schedules any needed upgrades. Back in the Logistics and Purchasing department, Tom is busy with his regular work and does not need to take on the second job of maintaining and upgrading the services he created. When appropriate, the SOA Centre of Excellence asks for his opinion on new requirements and requests for enhancements related to the services he created.

Conclusion

A summary of lessons learned from this scenario -- first the problems of an environment without SOA governance:

  • Service users are not registered with service owners or maintainers, and so no one knows who the users are or how many there are.
  • Absence of documented agreements between service users and service owners on technical and business aspects of service use and maintenance means that there are no agreements on expected uptime, number of concurrent users, and so on.
  • The organization as a whole may be affected by unplanned downtime.

And here are some of the benefits of using Service Registry for service governance:

  • Impact analysis can predict the effect of changes to services and the services environment.
  • Service use can be monitored and measured.
  • Documents of Understanding and Service Level Agreements spell out such issues as cost sharing, funding, ownership, and terms of use.
  • Service creation, access, and maintenance is monitored and controlled by an SOA Centre of Excellence.

Downloads

DescriptionNameSize
Code sampletestRESTQuery.zip2 KB
Code sampleWSDLLoader.zip5 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=600920
ArticleTitle=Getting started with WebSphere Service Registry and Repository
publish-date=12152010