Skip to main content

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

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

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.

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

All information submitted is secure.

  • Close [x]

A new approach to UDDI and WSDL, Part 5: Query from a Java application using the new OASIS UDDI WSDL Technical Note

John Colgrave (colgrave@uk.ibm.com), Senior Software Engineer, IBM United Kingdom Limited
John Colgrave is the architect of the IBM WebSphere UDDI Registry and a member of the OASIS UDDI Specifications Technical Committee. He is one of the authors of the new OASIS UDDI Technical Note on using UDDI and WSDL.

Summary:  Learn how to apply the approach defined in the new OASIS UDDI Technical Note to query from a Java application in this fifth paper in a series that outlines a new approach to using WSDL and UDDI, as described in the Technical Note.

View more content in this series

Date:  02 Nov 2004
Level:  Advanced
Also available in:   Japanese

Activity:  3947 views
Comments:  

In the first paper in this series (see Resources for links to Parts 1,2,3 and 4) you learned about a new approach to constructing a UDDI model of a WSDL description. The second paper described the types of UDDI query this new approach enables, with examples of several queries given in the form of UDDI V2 API requests. The third presented a more complex example than the one in the Technical Note, including screen shots showing you how to publish the UDDI entities and how to construct the types of query described in the Technical Note and in Part 2. The fourth part presented some example Java code showing you how to publish WSDL descriptions to UDDI programatically.

In this fifth paper you see some sample Java code that can issue the queries described in other examples in this series using UDDI4J.

The UDDI registry

The UDDI registry used in this example is an instance of the UDDI implementation that is shipped with IBM® WebSphere® Application Server Network Deployment, V5.1.

See Part 4 for additional details. You can obtain the results described here by running the sample in Part 4 against a clean registry and then running the sample described here.


Level of abstraction

The API presented here is at a fairly low level of abstraction in that the caller is required to know that, for example, a portType is mapped to a tModel and to know the various keys.


API structure

The API is structured as a single Java class that is a wrapper around an instance of the UDDI4J UDDIProxy class. An instance of the Query class is constructed from an instance of the UDDIProxy class. The Query class provides methods to query each of the entities used in the WSDL Technical Note. For example, there are two methods that return portType tModels. The first takes as parameters only the namespace name and the portType name, either of which can be null. The second has an additional parameter that is a categoryBag that you can use in the query in addition to the WSDL-related information.


API details

As mentioned before, the API is a single Java class; its fully-qualified name is uddi.wsdl.v2.query.Query, and the class has a constructor and eight public methods. Listing 1 shows the class and the constructor.


Listing 1. Definition of the Query class and its constructor
package uddi.wsdl.v2.query;

import java.util.Vector;

import org.uddi4j.UDDIException;
import org.uddi4j.client.UDDIProxy;
import org.uddi4j.response.BindingDetail;
import org.uddi4j.response.ServiceInfo;
import org.uddi4j.response.ServiceInfos;
import org.uddi4j.response.ServiceList;
import org.uddi4j.response.TModelInfo;
import org.uddi4j.response.TModelInfos;
import org.uddi4j.response.TModelList;
import org.uddi4j.transport.TransportException;
import org.uddi4j.util.CategoryBag;
import org.uddi4j.util.FindQualifier;
import org.uddi4j.util.FindQualifiers;
import org.uddi4j.util.KeyedReference;
import org.uddi4j.util.TModelBag;
import org.uddi4j.util.TModelKey;

public class Query {
    private final static String WSDL_ENTITY_TYPE_TMODELKEY = 
    "uuid:6e090afa-33e5-36eb-81b7-1ca18373f457";

    private final static String WSDL_ENTITY_TYPE_KEYNAME = 
    "WSDL entity type";

    private final static String XML_NAMESPACE_TMODELKEY = 
    "uuid:d01987d1-ab2e-3013-9be2-2a66eb99d824";

    private final static String XML_NAMESPACE_KEYNAME = 
    "XML namespace";

    private final static String WSDL_PORTTYPE_REFERENCE_TMODELKEY = 
"uuid:082b0851-25d8-303c-b332-f24a6d53e38e";

    private final static String WSDL_PORTTYPE_REFERENCE_KEYNAME = 
    "WSDL portType reference";

    private final static String PROTOCOL_CATEGORIZATION_TMODELKEY = 
    "uuid:4dc74177-7806-34d9-aecd-33c57dc3a865";

    private final static String PROTOCOL_CATEGORIZATION_KEYNAME = 
    "protocol";

    private final static String TRANSPORT_CATEGORIZATION_TMODELKEY = 
    "uuid:e5c43936-86e4-37bf-8196-1d04b35c0099";

    private final static String TRANSPORT_CATEGORIZATION_KEYNAME = 
    "transport";

    private final static String XML_LOCAL_NAME_TMODELKEY = 
    "uuid:2ec65201-9109-3919-9bec-c9dbefcaccf6";

    private final static String XML_LOCAL_NAME_KEYNAME = 
    "XML local name";

    private UDDIProxy proxy;

    public Query(UDDIProxy proxy) {
        this.proxy = proxy;
    }
}

The parameter of the constructor is an instance of a UDDI4J proxy, which is assumed to be configured with the appropriate URLs, and so on.

The eight methods are made up of four sets of methods, one set for each of the different UDDI entities that can be queried:

  1. query_portType_tModel
  2. query_binding_tModel
  3. query_bindingTemplate
  4. query_service

There are two methods in each set. With the exception of query_bindingTemplate, the difference between the methods of each set is that one method takes an extra parameter of a categoryBag, which you should use in the query in addition to the information relating strictly to WSDL. The second query_bindingTemplate method takes additional parameters of the keys of tModels representing the protocol and the transport and is used when you desire an implementation of a particular protocol or transport. Each of these sets of methods is described further in the following sections.


Method sets

query_portType_tModel

Listing 2 shows the query_portType_tModel method that takes only the WSDL-related information.


Listing 2. The WSDL-only query_portType_tModel method
public TModelList query_portType_tModel(String namespaceName,
                                        String portTypeName)
        throws TransportException, UDDIException {
    return query_portType_tModel(namespaceName, portTypeName, null);
}

Listing 3 shoes the query_portType_tModel method that takes an extra parameter.


Listing 3. The query_portType_tModel method that takes an extra parameter
public TModelList query_portType_tModel(String namespaceName,
                                        String portTypeName,
                                        CategoryBag categoryBag)
        throws TransportException, UDDIException {
    if (categoryBag == null) {
        categoryBag = new CategoryBag();
    }
    KeyedReference wsdlEntityTypeKR = new KeyedReference(
        WSDL_ENTITY_TYPE_KEYNAME, "portType",
        WSDL_ENTITY_TYPE_TMODELKEY);
    categoryBag.add(wsdlEntityTypeKR);
    if (namespaceName != null) {
        KeyedReference xmlNamespaceKR = new KeyedReference(
            XML_NAMESPACE_KEYNAME, namespaceName,
            XML_NAMESPACE_TMODELKEY);
        categoryBag.add(xmlNamespaceKR);
    }
    return queryTModel(portTypeName, categoryBag);
}

The query_portType_tModel method does the following:

  1. It adds a WSDL entity type keyedReference with a value of portType to the categoryBag.
  2. If the namespace name parameter is not null, then it adds an XML namespace keyedReference to the categoryBag.
  3. It invokes a private queryTModel method with all of the information and returns the result of this private method.

Listing 4 shows the private queryTModel method.


Listing 4. The queryTModel method
private TModelList queryTModel(String name, CategoryBag categoryBag)
        throws TransportException, UDDIException {
    FindQualifiers findQualifiers = new FindQualifiers();
    Vector findQualifierVector = new Vector();
    findQualifierVector.add(new FindQualifier("exactNameMatch"));
    findQualifierVector.add(new FindQualifier("caseSensitiveMatch"));
    findQualifiers.setFindQualifierVector(findQualifierVector);

    return proxy.find_tModel(name, categoryBag, null, findQualifiers,
        Integer.MAX_VALUE);
}

Note that the code does an exact case-sensitive match on the name; it is assumed that the full name is passed in.

query_binding_tModel

Listing 5 shows the query_binding_tModel method that takes only a tModelKey.


Listing 5. The query_binding_tModel method that takes only a tModelKey
public TModelList query_binding_tModel(String portTypeTModelKey)
        throws TransportException, UDDIException {
    return query_binding_tModel(portTypeTModelKey, null);
}

Listing 6 shows the query_binding_tModel method that takes an additional parameter.


Listing 6. The query_binding_tModel method that takes additional parameters
public TModelList query_binding_tModel(String portTypeTModelKey,
                                       CategoryBag categoryBag)
        throws TransportException, UDDIException {
    if (categoryBag == null) {
        categoryBag = new CategoryBag();
    }
    KeyedReference wsdlEntityTypeKR = new KeyedReference(
        WSDL_ENTITY_TYPE_KEYNAME, "binding", WSDL_ENTITY_TYPE_TMODELKEY);
    categoryBag.add(wsdlEntityTypeKR);
    KeyedReference wsdlPortTypeReferenceKR = new KeyedReference(
        WSDL_PORTTYPE_REFERENCE_KEYNAME, portTypeTModelKey,
        WSDL_PORTTYPE_REFERENCE_TMODELKEY);
    categoryBag.add(wsdlPortTypeReferenceKR);

    return queryTModel(null, categoryBag);
}

The query_binding_tModel method does the following:

  1. It adds a WSDL entity type keyedReference with a value of binding to the categoryBag.
  2. It adds a portType reference keyedReference with a value of the portTypeTModelKey parameter.
  3. It invokes the private queryTModel method with all of the information and returns the result of this private method.

query_bindingTemplate

The first method takes only a single parameter which is the key of a tModel, either a portType tModel or a binding tModel. Listing 7 shows this query_bindingTemplate method.


Listing 7. The query_bindingTemplate method that takes just a tModel key
public BindingDetail query_bindingTemplate(String tModelKeyString)
        throws TransportException, UDDIException {
    TModelBag tModelBag = new TModelBag();
    TModelKey tModelKey = new TModelKey(tModelKeyString);
    tModelBag.add(tModelKey);

    return queryBindingTemplate(null, tModelBag);
}

Note that this method invokes the private queryBindingTemplate method directly; it does not invoke the other public query_bindingTemplate method.

The second takes two additional parameters which are the keys of a protocol tModel and a transport tModel. Listing 8 shows this query_bindingTemplate method.


Listing 8. The query_bindingTemplate method that takes three tModel keys
public BindingDetail query_bindingTemplate(String portTypeTModelKeyString,
                                           String protocolTModelKey,
                                           String transportTModelKey)
        throws TransportException, UDDIException {
    TModelList tModelList = null;
    CategoryBag categoryBag = new CategoryBag();
    if (protocolTModelKey != null) {
        KeyedReference protocolKR = new KeyedReference(
            PROTOCOL_CATEGORIZATION_KEYNAME, protocolTModelKey,
            PROTOCOL_CATEGORIZATION_TMODELKEY);
        categoryBag.add(protocolKR);
    }
    if (transportTModelKey != null) {
        KeyedReference transportKR = new KeyedReference(
            TRANSPORT_CATEGORIZATION_KEYNAME, transportTModelKey,
            TRANSPORT_CATEGORIZATION_TMODELKEY);
        categoryBag.add(transportKR);
    }
    tModelList = query_binding_tModel(portTypeTModelKeyString, categoryBag);
    TModelBag tModelBag = new TModelBag();
    TModelInfos tModelInfos = tModelList.getTModelInfos();
    Vector v = tModelInfos.getTModelInfoVector();
    int tModelCount = v.size();
    for (int i = 0; i < tModelCount; i++) {
        TModelInfo tModelInfo = (TModelInfo) v.elementAt(i);
        TModelKey tModelKey = new TModelKey(tModelInfo.getTModelKey());
        tModelBag.add(tModelKey);
    }

    FindQualifiers findQualifiers = new FindQualifiers();
    FindQualifier orAllKeys = new FindQualifier();
    orAllKeys.setText("orAllKeys");
    findQualifiers.add(orAllKeys);
    return queryBindingTemplate(findQualifiers, tModelBag);
}

The query_bindingTemplate method does the following:

  1. It queries binding tModels using the portType tModel key and the protocol and transport tModel keys, if they are not null.
  2. It adds each binding tModel to a tModelBag.
  3. It invokes a private queryBindingTemplate method with a findQualifier of orAllKeys to search for all services that have at least one binding Template that refers to at least one of the binding tModels and to accumulate the results of all binding Templates into a single result.

Listing 9 shows the private queryBindingTemplate method.


Listing 9. The queryBindingTemplate method
private BindingDetail queryBindingTemplate(
FindQualifiers findServiceFindQualifiers, TModelBag tModelBag)
        throws TransportException, UDDIException {
    BindingDetail overallBindingDetail = new BindingDetail();
    Vector overallBindingDetailVector = new Vector();

    ServiceList serviceList = queryService(null,
        tModelBag,
        findServiceFindQualifiers);
    ServiceInfos serviceInfos = serviceList.getServiceInfos();
    Vector serviceVector = serviceInfos.getServiceInfoVector();
    int serviceCount = serviceVector.size();
    for (int i = 0; i < serviceCount; i++) {
        ServiceInfo serviceInfo = (ServiceInfo) serviceVector.elementAt(i);
        String serviceKey = serviceInfo.getServiceKey();
        BindingDetail bindingDetail = proxy.find_binding(null,
            serviceKey,
            tModelBag,
            Integer.MAX_VALUE);
        overallBindingDetailVector.addAll(bindingDetail.getBindingTemplateVector());
    }

    overallBindingDetail.setBindingTemplateVector(overallBindingDetailVector);
    return overallBindingDetail;
}

query_service

Listing 10 shows the query_service method that takes just WSDL-related parameters.


Listing 10. The query_service method that just takes WSDL-related parameters
public ServiceList query_service(String namespaceName, String serviceName)
        throws TransportException, UDDIException {
    return query_service(namespaceName, serviceName, null);
}

Listing 11 shows the query_service method that takes the extra parameter.


Listing 11. The query_service method that takes an extra parameter
public ServiceList query_service(String namespaceName,
                                 String serviceName,
                                 CategoryBag categoryBag)
        throws TransportException, UDDIException {
    if (categoryBag == null) {
        categoryBag = new CategoryBag();
    }
    KeyedReference wsdlEntityTypeKR = new KeyedReference(
        WSDL_ENTITY_TYPE_KEYNAME, "service", WSDL_ENTITY_TYPE_TMODELKEY);
    categoryBag.add(wsdlEntityTypeKR);
    if (namespaceName != null) {
        KeyedReference xmlNamespaceKR = new KeyedReference(
        XML_NAMESPACE_KEYNAME, namespaceName,
        XML_NAMESPACE_TMODELKEY);
        categoryBag.add(xmlNamespaceKR);
    }
    // Must use keyedReference in categoryBag for service name
    if (serviceName != null) {
        KeyedReference xmlNamespaceKR = new KeyedReference(
            XML_LOCAL_NAME_KEYNAME, serviceName,
            XML_LOCAL_NAME_TMODELKEY);
        categoryBag.add(xmlNamespaceKR);
    }

    return queryService(categoryBag, null, null);
}

The query_service method does the following:

  1. It adds a WSDL entity type keyedReference to the categoryBag with a value of service.
  2. If a namespaceName is supplied, then it adds a keyedReference to the categoryBag for the XML namespace taxonomy.
  3. If a serviceName is supplied then it adds a keyedReference to the categoryBag for the XML local name taxonomy.
  4. It invokes a private queryService method to search for the services.

Listing 12 shows the private queryService method.


Listing 12. The queryService method
private ServiceList queryService(CategoryBag categoryBag,
                                 TModelBag tModelBag,
                                 FindQualifiers findQualifiers)
        throws TransportException, UDDIException {
    return proxy.find_service(null, null, categoryBag, tModelBag,
        findQualifiers, Integer.MAX_VALUE);
}


Sample

The purpose of the sample is to show how you can use the Query API to make most of the queries described in the Technical Note, given the limited model published to UDDI in Part 4.

Structure of the sample

The sample is written as a Java class with a main method. The fully-qualified name of the class is uddi.wsdl.v2.query.QuerySample. Listing 13 shows the class definition and the main method.


Listing 13. The class definition and main method of our sample application
package uddi.wsdl.v2.query;

import java.net.MalformedURLException;
import java.util.Vector;

import org.uddi4j.UDDIException;
import org.uddi4j.client.UDDIProxy;
import org.uddi4j.datatype.binding.BindingTemplate;
import org.uddi4j.response.BindingDetail;
import org.uddi4j.response.ServiceInfo;
import org.uddi4j.response.ServiceInfos;
import org.uddi4j.response.ServiceList;
import org.uddi4j.response.TModelInfo;
import org.uddi4j.response.TModelInfos;
import org.uddi4j.response.TModelList;
import org.uddi4j.transport.TransportException;
import org.uddi4j.util.CategoryBag;
import org.uddi4j.util.KeyedReference;

public class QuerySample {
    private final static String SOAP_PROTOCOL_TMODELKEY = 
    "uuid:aa254698-93de-3870-8df3-a5c075d64a0e";

    private final static String HTTP_TRANSPORT_TMODELKEY = 
    "uuid:68DE9E80-AD09-469D-8A37-088422BFBC36";

    public static void main(String[] args) {
        UDDIProxy proxy = new UDDIProxy();
        try {
            proxy.setInquiryURL(args[0]);
            try {
                Query query = new Query(proxy);
                queryPortTypeTModels(query);
                queryBindingTModels(query);
                queryBindingTemplates(query);
                queryServices(query);
            } catch (TransportException te) {
                te.printStackTrace(System.err);
            } catch (UDDIException uddie) {
                uddie.printStackTrace(System.err);
            }
        } catch (MalformedURLException murle) {
            System.err.println("inquiry URL malformed");
        }
    }
}

The main method expects a single argument, which is the inquiryURL to be used with the UDDI4J proxy. The main method constructs the UDDI4J proxy and then constructs an instance of the Query class using this UDDI4J proxy instance.

The main method then calls the following private static methods in turn, passing in the UDDI4J proxy:

  1. queryPortTypeTModels
  2. queryBindingTModels
  3. queryBindingTemplates
  4. queryServices

Each of these methods is described in the following sections.


Private static methods

queryPortTypeTModels

This method calls the query_portType_tModel method passing in just a namespace name and a portType name, no additional categoryBag is passed. Listing 14 (contained in this sidefile) shows the code for this method.

queryBindingTModels

This method queries the tModel representing the ManufacturerPortType portType and then uses the key of the tModel to query all bindings of that portType. It then does a second query to find the WS-I-conformant bindings of the tModel. This second query is not described in the Technical Note but demonstrates the use of additional information, in this case the categorization to indicate WS-I conformance. Listing 15 (contained in this sidefile) shows the code for this method.

queryBindingTemplates

This method makes four separate calls to query_bindingTemplate. The first is to query all implementations of the ManufacturerPortType portType, so it first of all finds the appropriate portType tModel and then calls query_bindingTemplate passing in the key of the portType tModel. The second query is for all implementations of the WS-I-conformant binding of the ManufacturerPortType portType, so it finds the appropriate binding tModel and then calls query_bindingTemplate passing in just the key of the binding tModel. The third query is for all SOAP implementations of the portType, so in this case the query_bindingTemplate method that takes three parameters is called, with the first parameter being the key of the portType tModel, the second being the key of the tModel representing the SOAP protocol, and the third being null. The fourth query is for all SOAP/HTTP implementations of the portType, so in this case all three parameters are used, with the third being the key of the tModel representing the HTTP transport. Listing 16 (contained in this sidefile) shows the code for this method.

queryServices

This method issues a simple query for the WarehouseA Warehouse service, passing in the namespace name and the service name. Listing 17 shows the code for this method.


Listing 17. The queryServices method
private static void queryServices(Query query)
        throws TransportException, UDDIException {
    System.out.println("\nQuerying the businessService for 
    the \"WarehouseA's Warehouse Service\" WSDL service (example of 
    query described in section 3.3.8 of the TN...)\n");

    ServiceList serviceList = query.query_service(
        "urn:x-warehousea.com:warehouse_service",
        "WarehouseA's Warehouse Service");
    ServiceInfos serviceInfos = serviceList.getServiceInfos();
    Vector v = serviceInfos.getServiceInfoVector();
    ServiceInfo serviceInfo = (ServiceInfo) (v.elementAt(0));
    String serviceKey = serviceInfo.getServiceKey();
    System.out.println("Service key is " + serviceKey);
}

Run the sample

To run the sample, execute the uddi.wsdl.v2.query.QuerySample class passing in a single argument which is the inquiryURL to be used. You should see output similar to that shown in Listing 18 (contained in this sidefile).


Conclusion

This paper described how to implement the approach to query from a Java application as defined in the Technical Note using UDDI4J. I provided a sample class which queries the UDDI model for the WS-I Sample Application.


Resources

About the author

John Colgrave is the architect of the IBM WebSphere UDDI Registry and a member of the OASIS UDDI Specifications Technical Committee. He is one of the authors of the new OASIS UDDI Technical Note on using UDDI and WSDL.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


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. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

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.

(Must be between 3 – 31 characters.)

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

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=23628
ArticleTitle=A new approach to UDDI and WSDL, Part 5: Query from a Java application using the new OASIS UDDI WSDL Technical Note
publish-date=11022004
author1-email=colgrave@uk.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers