Dynamic Discovery of Web Services

I l @ ve RuBoard

The ability to locate Web services is important ”you won't always be able to contact a Web service developer by e-mail or phone to obtain Web service URLs and WSDL files. What you need is a way to obtain service description and location information based on one or more pieces of information about the service. We'll look at two mechanisms ”one for discovering the Web services installed on a specific server (discovery) and another that provides a more global search for Web services (UDDI).

Discovering Services on a Server

Web Services Discovery protocol (also known as DISCO) defines a way to provide a Web service client with information about the Web services installed on a given server. DISCO comes in two forms: static and dynamic. A particular Web service can provide either a dynamic discovery ( VSDISCO ) file or a static discovery (DISCO) file to publish information about its Web service.

The information provided by DISCO can be used in two ways. At development time, you can add a Web reference to a source of DISCO information. This will create a proxy representing all the services on a server. Alternatively, at run time your application can programmatically access and use discovery information.

We'll examine how ASP.NET supports DISCO and also briefly look at where Web service discovery might lead in the future.

Static Discovery

In the case of static discovery, the client can consult a DISCO file that lists the Web services to be exposed. If you want to use a DISCO file to describe your Web services, you must create one from scratch and place it in an appropriate folder. In the case of the Web services we've used so far, an appropriate location would be the CakeCatalogService virtual directory. Here's an example of a simple static discovery file for a subset of the Web services provided by the CakeCatalogService:

 <?xmlversion="1.0" encoding="utf-8" ?> <disco:discoveryxmlns:disco="http://schemas.xmlsoap.org/disco/"> <contractRefref="http://fourthcoffee.com/CakeCatalogService/Catalog.asmx?WSDL" xmlns="http://schemas.xmlsoap.org/disco/scl/"/> <contractRefref="http://fourthcoffee.com/CakeCatalogService/Enquiry.asmx?WSDL" xmlns="http://schemas.xmlsoap.org/disco/scl/"/> <contractRefref="http://fourthcoffee.com/CakeCatalogService/Ordering.asmx?WSDL" xmlns="http://schemas.xmlsoap.org/disco/scl/"/> </disco:discovery> 

As you might expect, the discovery information is encoded as XML. Each Web service is advertised by a contractRef element. Once the client has retrieved this file, it can obtain the WSDL documents listed and use them to build a client-side proxy. When a client adds a Web reference to the DISCO file shown above, by providing the URL to it ( http://fourthcoffee.com/CakeCatalogService/CakeCatalog.disco ), the result will be a list of Web services available at that site, as Figure 18-14 shows.

Figure 18-14. You target a static DISCO file directly to obtain Web service information for a server.

Note

Discovery requires slightly different XML namespaces for the Web services you've seen so far. This will be explained shortly. If you try importing the DISCO file without making these namespace changes, you won't get the results discussed in this section.


One notable aspect of importing Web service information through a discovery document is that a single proxy file is created for all of the discovered Web services, as shown in Figure 18-15. This proxy file contains all of the individual proxy classes in a single package (namespace).

Figure 18-15. All the services defined in a DISCO file are exposed through a single proxy.

This approach can offer a definite advantage because it avoids some of the package conflicts that can arise when you import multiple Web services from one server, as described earlier. However, the single proxy can become cluttered and will need updating whenever any of the services change. The single proxy is also very sensitive to the use of XML namespaces. Each of the Web services must be defined with its own individual XML namespace using the WebServiceAttribute . (See Chapter 17 for details.) To use the sample Web services with the static DISCO file provided, you must edit them to specialize the Namespace property of the WebService attribute. Each class listed in the static DISCO file has a commented version of the WebService attribute with the required namespace extension. Simply replace the default namespace in the service with the one in the comment. An example of such a comment is shown here:

 // //****WhenyouneedtouseDISCO,youshouldreplace //****theWebServiceAttributewiththisone: // //@attributeWebServiceAttribute(  Namespace= // "http://fourthcoffee.com/CakeCatalog/Enquiry")  // /**@attributeWebServiceAttribute(  Namespace="http://fourthcoffee.com/CakeCatalog/ ")  */ publicclassEnquiryextendsSystem.Web.Services.WebService 

The XML namespace property is important because if the Web services share the same XML namespace, only one of them will show up in a combined proxy. The reasons for this are quite tortuous, but suffice it to say that you must define distinct XML namespaces to take advantage of DISCO. This applies as much to dynamic discovery as it does to static discovery.

Under the covers, Visual Studio .NET uses the disco.exe command-line tool to obtain the discovery files from a server. You can use this tool yourself to retrieve the documents and use them to build proxies manually or for visual inspection. (For more information on disco.exe, see the .NET Framework documentation.)

Dynamic Discovery

Dynamic discovery is similar to static discovery, with the primary difference being the way that the list of Web services is built up. With static discovery, only information on the Web services listed in the DISCO file stored on the server are fetched . In contrast, dynamic discovery tries to list all Web services below the specified virtual directory unless it is specifically instructed not to.

To initiate dynamic discovery, the client requests a document with a .vsdisco extension. All of the Web services you've seen in this book have a VSDISCO file automatically created for them by Visual Studio .NET. Here's an example of a typical VSDISCO file:

 <?xmlversion="1.0" ?> <dynamicDiscoveryxmlns="urn:schemas-dynamicdiscovery:disco.2000-03-17"> <excludepath="_vti_cnf" /> <excludepath="_vti_pvt" /> <excludepath="_vti_log" /> <excludepath="_vti_script" /> <excludepath="_vti_txt" /> </dynamicDiscovery> 

This file is as unexciting as it looks. When a client requests a VSDISCO file, the request is processed by an instance of the System.Web.Services.Discovery.DiscoveryRequestHandler class. The DiscoveryRequestHandler object recursively searches the directory containing the VSDISCO file and all of its subdirectories for Web service (ASMX) files. The DiscoveryRequestHandler object will publish information about each ASMX file that it finds.

The primary function of the VSDISCO file is to limit the scope of the search by specifying subdirectories that should not be searched. Each exclude element removes the specified directory from the list of those to be searched. The DiscoveryRequestHandler will search each subdirectory for another VSDISCO file or a static DISCO file. If it discovers a VSDISCO file, it will use the file to determine which subdirectories of the subdirectory it should search. If it finds a DISCO file, it will consider this a definitive statement of what should be exposed for this point in the hierarchy, so the services contained in the file will be added to the DiscoveryRequestHandler object's list of services and no further subdirectories will be searched below that point. Similarly, if no ASMX files or VSDISCO files are found in a directory, its subdirectories will not be searched.

Tip

If you intend to implement a dynamic discovery hierarchy, you should not place a DISCO and a VSDISCO file in same directory.


You can use dynamic discovery to create a proxy for the Web services on a server in the same way that you used static discovery ”by adding a Web reference. The result of specifying the CakeCatalogService.vsdisco file in the Add Web Reference dialog box is shown in Figure 18-16. The contents of CakeCatalogService.vsdisco are the same as those in the example VSDISCO file shown previously. Again, a single file (Reference.jsl) is created that contains proxies for the discovered Web services. All of these proxies are defined in the same package. The XML namespace caveat discussed in the previous section on static discovery applies here also ”if two or more services share the same XML namespace, only one of them will have a proxy generated for it and the others will be ignored. The sample project VsDiscoCakeClient shows this in action.

Figure 18-16. You target a dynamic DISCO file to obtain Web service information for a server.

You'll find a dynamic discovery file, Default.vsdisco, in the IIS root directory. If you query this file when you add a Web reference, you might discover all of the Web services deployed on the Web server (depending on how the Web server and its virtual directories have been configured). In a development environment, this can be a great advantage. However, this does have security implications if the server is visible from a nontrusted network. Therefore, the dynamic discovery protocol is not enabled by default. To enable it, you must uncomment the following line in your machine.config file (which resides in the \Windows\Microsoft.NET\Framework\ .NETVersion \CONFIG folder):

 <httpHandlers> <addverb="*" path="*.vsdisco" type="System.Web.Services.Discovery.DiscoveryRequestHandler, System.Web.Services,Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="false"/> 

In a similar vein, you should make sure that any potential users (anonymous or otherwise ) have permission to access all the directories that the DiscoveryRequestHandler is instructed to search. Failure to do this will lead to security problems when you add a Web reference to the VSDISCO file.

Note

In our humble opinion, dynamic discovery should be used only in a development environment. You should always use static discovery files on production servers.


Programmatic Discovery

You can access discovery information programmatically by creating an instance of the System.Web.Services.Discovery.DiscoveryClientProtocol class and instructing it to search for discovery information at a given URL. The following code fragment, from the sample project DiscoExaminer, shows a simple search:

 DiscoveryClientProtocoldcp=newDiscoveryClientProtocol(); DiscoveryDocumentdd=dcp.DiscoverAny ("http://fourthcoffee.com/CakeCatalogService/CakeCatalog.disco"); dcp.ResolveOneLevel(); DiscoveryClientDocumentCollectiondocs=dcp.get_Documents(); IDictionaryEnumeratorenumerator=docs.GetEnumerator(); while(enumerator.MoveNext()) { DictionaryEntryentry=(DictionaryEntry)enumerator.get_Current(); Console.WriteLine("\n" + "********************\n" +entry.get_Key() + "\n********************"); if(entry.get_Value()instanceofDiscoveryDocument) { DiscoveryDocumentdoc=(DiscoveryDocument)entry.get_Value(); doc.Write(Console.get_Out()); } } 

The DiscoveryClientProtocol object maintains a collection of discovery documents. You can populate this collection by calling the ResolveOneLevel or ResolveAll method. ( ResolveAll tries to resolve everything recursively.) You can then examine the documents in the collection and act on them as required. The result of running this code is shown in Figure 18-17.

Figure 18-17. Using the DiscoveryClientProtocol object to programmatically discover Web service information

The Future of Discovery

The DISCO protocol is a first-generation Web service discovery protocol. Work is ongoing as part of the GXA to create a second-generation discovery language called Web Services Inspection Language (WS-Inspection). WS-Inspection is a joint effort between Microsoft and IBM to consolidate their previous, proprietary discovery protocols (DISCO and ADS, respectively) to provide a lightweight, standard Web services discovery protocol. For more information on WS-Inspection, see http://www.msdn.microsoft.com/library/en-us/dnglobspec/html/wsinspecspecindex.asp.

Discovering Services Through UDDI

UDDI provides a mechanism that allows an organization or an application to discover information about services offered by other organizations. UDDI data is held in a database called the UDDI registry. A UDDI registry contains essentially two types of information:

  • Business information, including contact information and the categories under which the business should be listed. Categorization of businesses helps users find the right business more easily. Various categorization schemes are available.

  • Service information, including the type of service and how to use it. A service can be anything from a consultancy service (whose interface would be a telephone number or a Web site) to a Web service that's described using WSDL. The rest of this section will concentrate on Web services.

You can search the UDDI registry in three ways. If you know the name of the organization you're looking for, you can search based on the name . This is called a white pages search (after that type of telephone directory). If you know only the type of business you're looking for, such as financial services, you can perform a search based on this type. This is termed a yellow pages search , again after that type of telephone directory. Finally, you can search based on the type of service, such as a particular interface description. This is known as a green pages search . Once you've found one or more organizations that match your requirements, you can obtain that service information, typically a WSDL description, and plug this information into your applications. There are many wider issues surrounding this style of Web service interaction, such as the need to agree on commercial terms. However, for the purposes of this chapter, we'll focus just on the technical side of things.

UDDI Registry Information

This chapter is not meant to provide a comprehensive description of UDDI, but the following information should help you to understand better what's going on.

You've seen that WSDL documents contain both the description of a service ( portType elements and binding elements) and the location information ( service and port elements). The UDDI standard defines two structures for these purposes. The tModel structure describes the service; in WSDL terms, this includes the complex type schema, in and out message definitions, portType elements, and binding elements. This forms a location-independent "interface" that can be shared by multiple service implementations that offer the same "interface." The UDDI bindingTemplate structure contains location information for a particular service. This equates to information defined in the WSDL port and service elements.

UDDI defines additional structures. A UDDI businessService structure combines a set of bindingTemplate structures into a logical service group . These, in turn , are contained in a businessEntity structure, where the contact information and description of the organization also reside.

You can use UDDI registries in several ways. There are a few global UDDI registries in which any registered company can store information. Examples include the public UDDI registries run by Microsoft, IBM, and XMethods. You can find information about accessing these registries at http://www.uddi.microsoft.com, http://www-3.ibm.com/services/uddi/, and http://www.services.xmethods.net/, respectively. Microsoft and IBM provide both a test registry and a live registry.

As UDDI matures, local and private registries (on intranets , for example), are being put in place to store information about the services offered by specific organizations. An intranet version of UDDI will be available in .NET Server. Whether public or private, a UDDI registry can be used at design time to locate services and integrate them into an application or at run time to check that the service location is up-to-date.

To use service information located in a UDDI registry, you add a Web reference to your application. This generates a proxy for that service that you can use in your application. For example, the Microsoft entry in the company's public UDDI registry contains a description of how to access a UDDI registry. You can import this description into your application and use it. To start the import process, choose Add Web Reference from the Project menu and select the UDDI Registry link in the Add Web Reference dialog box (as shown in Figure 18-18) to use the Microsoft UDDI registry. Alternatively, you can type the URL of another UDDI registry and import service descriptions from there.

Figure 18-18. You select the UDDI Registry link to search the public UDDI registry.

Next , you enter the business name to search for ”Microsoft in this case, as shown in Figure 18-19.

Figure 18-19. Searching for a business in the public UDDI registry

The next page lists the services offered by this company. One service is currently offered ”UDDI itself, as shown in Figure 18-20.

Figure 18-20. The one service offered is UDDI.

If you select uddi-org:inquiry, you'll see the WSDL description, as shown in Figure 18-21.

Figure 18-21. The UDDI service is described in WSDL.

Selecting Add Reference will create a proxy for this service in your project. The proxy classes are created in the org.uddi.www package. The main class is called InquireSoap , which provides a method for all of the SOAP messages in the UDDI specification that relate to enquiry. This is quite a complex API, and it is not possible to discuss it in detail here. Suffice it to say that if you want to obtain information from a UDDI registry, this proxy class will allow you to send those messages. One thing worth noting is that no default URL is associated with the proxy class. You have to decide which UDDI registry you want to query and then set the Url property appropriately. An example of the result of importing this UDDI proxy can be found in the sample project UDDIClient.

If you want to develop applications that register entries in a UDDI registry or submit queries to one, you can use the Web service interfaces you've just seen. Alternatively, you can download the Microsoft Universal Description Discovery and Integration .NET Software Development Kit (UDDI .NET SDK). This SDK provides a set of components that allow a .NET developer to interact with a UDDI registry.

I l @ ve RuBoard


Microsoft Visual J# .NET (Core Reference)
Microsoft Visual J# .NET (Core Reference) (Pro-Developer)
ISBN: 0735615500
EAN: 2147483647
Year: 2002
Pages: 128

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net