Wednesday, May 19, 2010

Fetching WSDL Properties From WebSphere Service Registry and Repository (WSRR) In WebSphere Integration Developer (WID) Using REST Calls

Summary:
Learn how to Query WSRR using REST calls to fetch content and parse this content. In particular, the scenario of fetching a property value on a particular WSDL without using the IBM WSRR (Java (EJB) or SOAP) API is discussed. We will use a regular Java class to make REST calls to WSRR and parse thorough the retrieved content.


WebSphere Integration Developer (WID) 6.2 offers Endpoint Lookup mediation primitive to be used in mediation modules to lookup the endpoint of a particular service from WebSphere Service Registry and Repository (WSRR), but for scenarios where you have the endpoint or any other service related information stored as a property on the WSDL in WSRR, fetching a property without using the IBM WSRR (Java (EJB) or SOAP) API is discussed. We will use a regular Java class to make REST calls to WSRR and parse thorough the retrieved content.

Querying WSRR for Content:

You could use XPath expressions to query content in WSRR. Two types of Queries

Graph Query
The URL format for a REST call using Graph Query is:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/GraphQuery?query=<XPath expression>

Example:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/GraphQuery?query=/WSRR/WSDLDocument
[@name=’MyWebService.wsdl’ and @version=’1.0’]

The above URL will fetch the metadata associated with a 1.0 version of the WSDL named “MyWebService.wsdl”.

Property Query
The URL format for a REST call using Graph Query is:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/PropertyQuery?query=
<XPath expression>&p<#>=<property name>

# denotes a number starting from 1 and incremented by 1 for each additional property that you want to fetch.

You can use “&p<#>=<property name>” once for each property that you want to retrieve.The order of the #s can change.

Example:

http://<host>:<port>/WSRR/6.1/Metadata/
XML/PropertyQuery?query=/WSRR/WSDLDocument
[@name=’MyWebService.wsdl’ and @version=’1.0’]
&p1=name&p2=endpoint

Note: Make sure you use %27 for ‘, when you are using the URL from the browser to view the content.

Let us consider the scenario where I have a WSDL stored in WSRR with a property named ‘endpoint’. The value of the property will hold the endpoint URI for that service.

In-order to invoke a service from WID, we can create a utility class that hold the methods to fetch the information from WSRR and we can use this utility from any mediation. Once the endpoint is retrieved, you can save that information on the SMO to invoke your service dynamically with the fetched endpoint value.

The path on the SMO to store the endpoint for dynamic invocation is “smo/headers/SMOHeader/Target/address”.

Make sure you also select the “Use dynamic endpoint if set in the message header” option under “Details” section in the “Properties” view of either the “Callout” node or the “Service Invoke” primitive.

Fetching the property value involves two steps:

1. Fetch the content using REST call with a property query.
String resturl = "http://<host>:<port>/
WSRR/6.1/Metadata/XML/PropertyQuery?
query=/WSRR/WSDLDocument[@name=%27
MyWebService.wsdl%27%20and%20
@version=%271.0%27]&p2=name&p1=endpoint";
URL url = new URL(resturl);
URLConnection urlConnection = url.openConnection();
BufferedReader reader = new BufferedReader
(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
String line = null;
while(null != (line = reader.readLine()))
            stringBuffer.append(line);
reader.close();

2. Parse the fetched content using an xml parser to read the value of the property.

String searchPath = "//*[local-name()='property'
 and @*[local-name()='name'='endpoint']]
/@*[local-name()='value']";
DocumentBuilder documentBuilder =
DocumentBuilderFactory.
newInstance().newDocumentBuilder();
Document contentDocument = documentBuilder.
parse(new InputSource(new StringReader
(stringBuffer.toString())));
XPath xPath = XPathFactory.
newInstance().newXPath();
XPathExpression xPathExpression = xPath.
compile(searchPath);
String  endpoint = (String)xPathExpression.
evaluate(contentDocument,XPathConstants.STRING);

The string endpoint will hold the value against the property named “endpoint” on the WSDL “MyService.wsdl” and version 1.0 that is in WSRR.

You could basically use the same method to fetch the value of any property on the WSDL. You can also fetch any other content from WSRR by creating appropriate queries using REST calls.

If you would like to use SOAP or Java (EJB) API for WSRR, you will need to use two jar files named
  • sdo-int.jar
  • ServiceRegistryClient.jar
You can find these jars in the installation directory of WSRR.

For more information on using the IBM API for WSRR use references below.

References:
  1. Using DataPower SOA Appliances to query WebSphere Service Registry and Repository.
  2. WebSphere Service Registry and Repository Handbook.
  3. Query Content in WSRR – (WSRR Information Center).
  4. SOAP API Guide – (WSRR Information Center)

2 comments:

  1. Hi Please let me know how to frame a querystring/URL to retrieve wsdl,xsd,xsl which are present in a serviceVersion off WSRR8.5 by not mentioning the WSDL/XSD/XSL name .
    Should retrieve the artifacts using serviceVersionName and Version

    ReplyDelete
  2. Hi Lavanya,

    It is not clear if you would like to retrieve the WSDL and XSD content itself or you want to retrieve metadata related to the documents.

    If you would like to get the content of WSDL or XSD itself, you could use a URI that looks something like.
    http://{host}:{port}/WSRR/{version}/Content/{bsrURI}

    If you like to fetch the content based on some properties, you could run a property query to fetch the bsrURI of the object that you are interested in and then run the above Content REST call using the bsrURI value to fetch the actual document.

    For WSDL Document:
    http://{host}:{port}/
    WSRR/{version}/Metadata/XML/PropertyQuery?
    query=/WSRR/WSDLDocument[@{property name1}=%27
    {value}%27%20and%20
    @{property name2}=%27{value}%27]&p1=bsrURI

    For XSD Document:
    http://{host}:{port}/
    WSRR/{version}/Metadata/XML/PropertyQuery?
    query=/WSRR/WSDLDocument[@{property name1}=%27
    {value}%27%20and%20
    @{property name2}=%27{value}%27]&p1=bsrURI

    If the service version name and the version are the properties that you would like to base your query on, then use the corresponding names and values in the above queries. You could use as many properties on the query as you would like.

    ReplyDelete