Microsoft uses UDDI at run time
Karsten Januszewski
Microsoft Corporation
December 2001
Summary:This article outlines the use of UDDI at run time, discussing the infrastructure of UDDI (provided by the public Registry and UDDI Services in Microsoft Windows. NET Server) as a WEB service to support client applications.
Directory
- Brief introduction
- UDDI Runtime Infrastructure
- Sample Scenarios
- Create a Web service: C #. NET. asmx
- Using WEB services: C # Windows forms. NET Client
- Other programmes
- Summarize
Brief Introduction
UDDI (common description, Discovery, and integration) is often referred to as the "Yellow Pages" of WEB services. While this category of yellow Pages is useful for helping understanding, it does not fully reflect how UDDI is merged into a web-based software architecture. The Yellow Pages analogy deals only with the design-time usage of UDDI, which is the ability to find and use WEB services by searching based on keywords, categories, or interfaces. From a design-time perspective, the Yellow Pages analogy is very accurate: as the Yellow Pages classify and catalog businesses and their phone numbers, UDDI classifies providers and their Web services into catalogs. Developers can look for WSDL files and entry points in UDDI, and then incorporate those WEB services into the client application.
However, UDDI does not just provide design-time support. The Yellow Pages analogy does not mention how UDDI supports runtime. UDDI will play an important role when the discovery process is over. The ability to programmatically query UDDI at run time enables UDDI to be used as an infrastructure for building reliable and robust WEB service applications.
UDDI Runtime Infrastructure
When you integrate a Web service into a client application, you need to consider the problems that you may encounter, one of the key issues being the inability to predict or detect the failure of the provider that provides the Web service, or recover from a failure. What can a client application do if a Web service fails? How does an application recover from a failed WEB service invocation appropriately and dynamically?
Similarly, how does the owner of a Web service dynamically update changes from a Web service provider's perspective? We need to consider moving the WEB service to a new server. How can I notify a client of a WEB service in a way that this change is effective? How does the owner distribute this information at run time without causing disruption to all clients of the WEB service?
In these cases, UDDI can play a very important role in providing the infrastructure to support run-time WEB services. UDDI addresses these "quality of service" issues by defining calling rules, which include caching binding information, such as the entry point of a Web service, and other parameters for this particular implementation. In the event of a failure, the client can issue a run-time UDDI query that refreshes the cached information with the latest information.
The mode of the above provision is as follows:
- Look for Web services in UDDI. Use the WSDL file of this Web service (represented by UDDI TModel), as well as the implementation details of entry points and other configuration information, all of which are contained in UDDI Bindingtemplate.
- Prepares a client application for a specific Web service. In the client application, cache the unique bindingkey of the Web service so that all the information needed is retrieved from UDDI when the application is first used.
- When an application invokes a remote Web service, the cached data obtained from the UDDI Web registry is used.
- If the call fails, the Bindingkey value and the Get_bindingtemplate API for the UDDI registry are invoked to get the new binding information.
- Compare the old and new information: If different, retry the failed call. If the retry succeeds, the cached data is replaced with new data and the new data is stored for later invocation. However, if the binding information returned is the same, the provider does not make any updates and an error occurs in the application. Similarly, if there is a new binding information, but the call still fails, the application can also have an error.
From the Web service provider's perspective, the provider should know when the UDDI entries for the Web service can be updated. When the provider of a Web service needs to redirect traffic to a new location or need to back up the system, the provider simply activates the backup system and then changes the entry point in the UDDI registry. This method, called Retry on failure, provides a mechanism for the client to recover from a failure at run time.
Sample Scenarios
We can look at an example to see how this pattern works. This sample scenario involves a scenario for a fictitious company that needs to provide real-time sales data to its internal departments. Therefore, this WEB service is not exposed and is used only within the firewall.
First, we need a WEB service. In this case, we will provide a very simple WEB service that supports only Getsalestotalbyrange, a method that enables clients to obtain a transient graph of real-time sales data within a certain date range.
The next step is to create a client that uses this WEB service. We configured the client to cache entry points and Bindingkey information, and set up a mechanism for clients to flush the client cache from the UDDI registry in the event of a failure.
Create a Web service: C #. NET. asmx
The Microsoft. NET framework greatly simplifies the authoring of WEB services. In this case, we'll create a simple Web service that contains only a Getsalestotalbyrange method that uses two dates as input parameters and returns two parameters. The following is an. asmx page that has achieved this goal, Salesreport.asmx:
This page should be added to the virtual directory. To make the client sample work, create a virtual directory named Salesreportusa (http://localhost/SalesReportUSA/SalesReport.asmx). Note that this WEB service always returns 5000.00 as the return value. (It would be nice if the sales report had such predictability!) Real-world applications should use database tuning to retrieve this information. For this example, only a hard-coded value is required.
The next step in deploying this WEB service is to register the service in the UDDI registry. This UDDI registry is an internal UDDI server and does not make any sense to expose this Web service. Microsoft provides local UDDI services through Microsoft®windows®.net Server. For more information about this feature, see the Windows. NET Server (English) Web site. If you do not have Microsoft. NET Server installed, you can use the Microsoft UDDI Software Development Kit (SDK) to install UDDI on your local computer.
There are two ways to register a Web service in UDDI: You can register with the Web user interface or programmatically register a Web service by using a UDDI SDK. The SDK is easy to use, and you can refer to the code examples published in the Web service description and Discovery column using UDDI. Whichever method you use, you need to register the WSDL file for the Web service as TModel first. UDDI TModel are XML entities that represent interfaces and abstract metadata, so the WSDL file is represented as TModel. Then, you need to register the WEB service's entry point as bindingtemplate. The UDDI bindingtemplate is an XML structure that represents the implementation details for a given WEB service. For more information about the UDDI architecture and its relationship to WSDL, see http://www.uddi.org (English) and UDDI "Best practices" document Using WSDL in a UDDI Registry 1.05 (English).
The following is an example of a UDDI bindingtemplate structure that was obtained after using UDDI Services to complete the above steps. Note that Servicekey, Bindingkey, and tModelKey are all generated by UDDI and are unique to the entities we save. Keywords generated by other UDDI registries will vary.
<bindingtemplate servicekey= "Ef25102d-2171-454c-ade9-3dd7a4a914ee" bindingkey= " F46fced9-2b8a-4817-b957-f8d8aca0a2f9 "> <accesspoint urltype=" http "> http://localhost/ Salesreportusa/salesreport.asmx </accessPoint> <tModelInstanceDetails> <tmodelinstanceinfo TM odelkey= "uuid:b28fe40a-ea62-4657-88d5-752d8a6cdf77"/> </tmodelinstancedetails></bindingtemplate >
In the above structure, we highlight the entry point and Bindingkey for this WEB service. This is important for the customer to understand both parts of the information. In addition, if a client needs to obtain the WSDL for this Web service, you can use tModelKey to query UDDI to get the TModel.
using Web services: C # Windows forms. NET client
Now we can switch roles and look at the client part of the application. At design time, we might be able to find this Web service in UDDI. We will download the corresponding WSDL file and use the Microsoft Visual studio®.net
Add Web Reference(add Web Reference) or WSDL.exe to generate a proxy class. (WSDL.exe is a command-line tool that is part of the Microsoft. NET Framework SDK.) )
You can now start writing logic in the client application. In this case, it is a C # Windows forms application called SalesReportClient.exe that allows users to query the sales report information.
First, you need to add the UDDI. NET SDK classes to your project, and you can download these classes. (Microsoft UDDI SDK version 1.5.2 [English] is compatible with Visual Studio. NET Beta 2; Microsoft UDDI. NET SDK Beta version 1.75 [English] and Visual Studio . NET Release Candidate compatible. )
usingThe statement reads as follows:
Using system;using system.drawing;using system.collections;using system.componentmodel;using System.Configuration; Using system.windows.forms;using system.data;using microsoft.uddi;using Microsoft.Uddi.Binding;
Then, you need to store the entry point for the UDDI server where the Web service resides (after all, UDDI itself is a Web service). To do this, you need to create an application configuration file for this. exe executable file to store the location of the UDDI server. The Bindingkey of the Web service will also be stored in this configuration file. By using XML configuration files in. NET, you can add as many appsetting as you want, and the application can be fetched through the collection.
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <appSettings> <add key= "Uddi_url" value = "Http://localhost/uddi/api/inquire.asmx"/> <add key= "Bindingkey" F46fced9-2b8a-4817-b957-f8d8aca0a2f9 "/></appsettings></configuration>
In this example, we point to a Microsoft UDDI Developer Edition server that resides on its own computer. Uddi_url can also be one of the public UDDI nodes, or a UDDI registry residing within the enterprise. Use the configuration file app.config naming convention to save this file. After the application is compiled, the configuration file is placed in the/bin directory and named with its own. exe name.
This step that you just completed (adding configuration information about the WEB service) is no different from how Visual Studio. NET publishes the URL Behavior property on each Web reference that you add to your project. By changing this property to
Dynamic, Visual Studio. NET can create a configuration file that contains Web service entry points. The above operation extends this concept further by providing the ability to requery UDDI at run time. Therefore, the configuration file contains the entry point of the UDDI node and the bindingkey of the Web service.
Now we can start coding the application itself. First you need to create a text box, a label, a button, and a two date time selector. Then set up some global variables:
Some variables of the application private string inquiryurl = null; private string bindingkey = null; private string accesspoint = null; Private Bindingtemplate BT; Private double salesfigure = 0;
After the form is instantiated, we need to initialize the following variables:
Public Form1 () {////windows form Designer support required//InitializeComponent (); Import variable from configuration file Inquiryurl = configurationsettings.appsettings["Uddi_url"]; Bindingkey = configurationsettings.appsettings["Bindingkey"]; BOOL Initcache = Refreshcachefromuddi (); if (Initcache = = true) Accesspoint = Bt. Accesspoint.text; }
The Refreshcachefromuddi () function is used to query a UDDI server to find entry points. Use the UDDI SDK to perform a UDDI API call (getbindingdetail) to pass Bindingkey as a parameter.
private bool Refreshcachefromuddi () { //used UDDI SDK, setting the UDDI entry point inquire.url = inquiryurl; //Create Get_bindingdetail UDDI API message getbindingdetail GBD = new Getbindingdetail (); //add BINDINGKEY&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;GBD. Bindingkeys.add (Bindingkey); try { bindingdetail bd = GBD. Send (); //If successful, use the first template in the return collection //Update Bindingtemplate Object &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;BT = BD . Bindingtemplates[0]; return true; } catch (Exception ERR) { textbox1.text + = Err. Message; return false; } }
While the application is running, we place the entry point in the variable. If the user wants to restart the application, it will requery the entry point in UDDI, so the application always has the latest changes to the WEB service. If you want, you can cache these data in a file system or database.
Next, you need to create a function that invokes the WEB service itself:
private bool Invokewebservice () { localhost. salesreport sr = new localhost. SalesReport () //Set entry point for proxy class &NBSP;&NBSP;&NBSP;&NBSP;SR. URL = accesspoint; try { salesfigure = Sr. Getsalestotalbyrange (datetimepicker1.value, datetimepicker2.value); label1. Text = "Sales Chart of selected date: $" + salesfigure.tOstring (); textbox1.text + = "Web service invocation succeeded!" "; return true; } catch (Exception Err) { textbox1.text = Err. Message; return false; } }
Finally, when the user clicks the button, the application attempts to invoke the Web service.
private void Button1_Click (object sender, System.EventArgs e) { cursor.current = cursors.waitcursor; //attempt to invoke the Web service bool webservicesuccess = Invokewebservice (); //If it fails, the query uddi if ( Webservicesuccess = = False) { textbox1.text + = "Web service failed. Requery uddi to get a new entry point. \ n \ bool uddisuccess = Refreshcachefromuddi (); //re-query UDDI succeeded, if (uddisuccess = = True) { //compares the original entry point with the new entry point //determine if any changes have been if (Accesspoint.equals) (BT. Accesspoint.text) = = False) { //If the entry point is different, it must be a new //Reset Variable accesspoint = Bt. accesspoint.text; // And try calling the Web service again webserVicesuccess = Invokewebservice (); // Unable to invoke WEB service with new information new info if (webservicesuccess = = False) { textbox1.text + = "Web service failed again. Updated in UDDI entry point is invalid! \ n '; } } else { textbox1.text = "UDDI does not provide new information. \ n '; } } else { TextBox1.Text + = "UDDI refresh failed. \ n '; } } }
Notice how you can set the entry point for the Web service proxy class at run time. Because all proxy classes are derived from System.Web.Services.Protocols.SoapHttpClientProtocol, the proxy class publishes a series of attributes. The Url property is one of them. Setting this property enables us to specify the entry point at run time. Then we can send a SOAP request over the line. If no exception occurs, all is normal and the data returned from the WEB service is displayed in the form. However, if an exception does occur, this function returns "false", and the calling code attempts to refresh the entry point from UDDI to reuse the Refreshcachefromuddi () function.
Once we requery UDDI, we compare the entry points returned by UDDI with the original entry point. If the entry point is the same, the provider has not updated UDDI with the new information, all we can do is try to contact the provider of the Web service and tell them that the Web service is not responding. However, if the entry points retrieved from UDDI are different, you can try to invoke the Web service again.
To simulate a failure, you can change the name of the Web service. Try to run the application. The UDDI entries are then updated with the new name of the Web service. Run the application again. The application will find a new entry point in UDDI, successfully query the new service, and then save this information. If you shut down the application completely and then reopen it, you should be able to invoke the Web service again the first time you try.
Other Programmes
This "retry On Failure" example discusses the support infrastructure that UDDI can use as a WEB service client at run time. In a future column, we will discuss other options, including:
- Optimize entry point Lookup-there may be multiple WEB services that support public interfaces that reside on different servers that are located in different physical locations. The client should use the most recent Web service. Through runtime UDDI lookups, customers can determine the best entry point based on the geographic classification of different services or other metadata associated with the implementation.
- Aggregation of data based on public interfaces-WSDL may define a standard Web service interface for searching directories. Many vendors in the industry can implement WEB service interfaces and publish entry points in UDDI. At run time, client applications can dynamically search these entry points and issue queries to collect such catalog data. In this way, the polling application can take advantage of runtime UDDI data.
In addition, we will discuss how to optimize the WSDL file so that it really acts as an interface specification file.
Summary
UDDI provides important run-time functionality that can be integrated into applications to create stronger dynamic clients. By using UDDI as an infrastructure in a WEB services architecture, you can write more robust applications.