Provisioning

Use Web Services Provisioning to Control Access, Usage, and Billing on Your Site

Chandu Thota

Code download available at:WebServicesProvisioning.exe(139 KB)

This article assumes you're familiar with C#, SQL, and SOAP

Level of Difficulty123

SUMMARY

Building Web Services to provide enterprise-level solutions is only the first step. You need to take care of the infrastructure aspects of your solution as well, including provisioning, billing, security, and reporting. In this article, the author uses the .NET Framework and SQL Server 2000 to design a provisioning system that will take care of all these housekeeping tasks. He discusses the general requirements of a Web Service provisioning system, walks through the implementation, and then outlines various scenarios for putting this system to work.

Contents

A WSP Primer
Building the WSP Framework
SOAP Message Interception Layer
SOAP Message Processing Layer
Data Storage Layer
Implementing the WSP System
Implementing Service Provision Manager
Publish a New Web Service
Managing Existing Services
Web Service Request Interception
Service Subscription Manager
Conclusion

Like just about everyone else these days, I'm under the spell of Web Services. As a managed developer, I'm even more fascinated because the Microsoft® .NET Framework makes it simple to put Web Services to use. The promise of these technologies—enterprise application integration and software as a service—make them a viable business solution. Of course, the moment you start thinking about developing Web Services as a real-world business solution, you realize that you're going to have to take care of various real-world business aspects such as provisioning, billing, security, and reporting.

In this article, I will discuss how to design a provisioning system using the .NET Framework and SQL Server™ 2000. I will begin by discussing the requirements of a Web Service provisioning (WSP) system, which I'll refer to simply as WSP. Then I'll examine the design aspects and coding. Finally, I will outline various scenarios for putting this system to work.

A WSP Primer

WSP is the technology I created for use in a pay-per-use Web Services scenario. WSP can be explained as a utility or supporting architecture that enables Web Services provisioning and subscription services for the two important roles that exist in the world of Web Services: the role of provider and the role of consumer. Web Service providers are service sellers who own, operate, and manage the Web Services. Web Service consumers subscribe, consume, and pay for the Web Services. It is also possible for a user to be both a provider and a consumer.

From an architectural perspective, WSP consists of five major applications working together. These include the service catalog, service subscription manager, service provision manager, metering and billing engine, and WSP runtime. Let's examine each of these applications briefly.

Service catalog This contains published services and the corresponding technical and licensing details. This is the first step for both service providers and service consumers in publishing and consuming a Web Service. A private or public Universal Description, Discovery, and Integration (UDDI) instance can also be used as a service catalog. Service providers usually publish the services and consumers discover them by browsing the catalog.

Service subscription manager This component automates the subscription and enrollment process. Service consumers discover the services and subscribe to them using the subscription manager. The subscription manager usually implements the licensing and contractual aspects of the WSP.

Provision manager Automation of the service publishing for the service providers is the role of this component. A provision manager is also used to specify the licensing and rating information.

Metering and billing engine The responsibility for processing the Web Service usage logs, calculating the rates based on the licensing agreements, and presenting the bills to the service providers and consumers on a periodic basis fall on this component.

WSP runtime This is the most important piece of the WSP system. It is responsible for intercepting the incoming SOAP messages for authorization, license evaluation, and logging the service usage.

Now, let's take some time to understand the WSP process flow. A service publisher logs on to the WSP system and uses provision manager to publish the service in the service catalog. This publication process includes specifying service details such as service description, service interface (the WSDL), service end-point, security model, licensing model, and access fees.

Once the publishing process has completed, the Web Service can only be accessed through the WSP runtime engine, with all incoming requests going through the WSP runtime. With each incoming request, the WSP runtime engine performs security (identity) and licensing checks before the request reaches the actual Web Service. All requests coming into the server must satisfy both the security and licensing checks; otherwise, access to the Web Service will be denied.

When an incoming request satisfies both security and licensing checks, the request is fulfilled and the usage details, such as the consumer identity and usage time, are logged into the database using the logging application.

The publisher can access the Web Service usage logs using the logging application. The publisher can also access the Web Service access fees (from the metering and billing engine) that are to be charged to a particular consumer. The metering and billing engine accesses the licensing and logging databases to calculate the access fees to be charged to the consumer (see Figure 1).

Figure 1 WSP Process Flow

Figure 1** WSP Process Flow **

Now let's take a look at the Web Service consumer process flow. A Web Service consumer uses the subscription manager to search and discover a Web Service. Upon discovering a Web Service that satisfies their business needs, the consumer completes the subscription process by providing information for the Web Service access security (such as their host name or IP address) and by choosing a licensing model that suits their needs.

Once the subscription process is completed, the Web Service is ready to be consumed. When a consumer invokes a Web service, the WSP runtime engine checks the identity and the licensing details and if they are satisfied, the service request is fulfilled and the usage details are logged in the logging database.

The Web Service usage logs now can be viewed by the Web Service consumer and the consumer can even view the access fees using the metering and billing engine. The consumer sees the same exact logs and access fees as the service publisher sees for this consumer.

Although the WSP system looks overly complicated at first glance, there are several advantages to using this system. For example, Web Services can be designed to perform only the business process tasks for which they are intended, so you really don't have to worry about implementing management, such as security, into the Web Service. Another advantage is that Web Service provision/federation is automated. Service monitoring and usage logs are available for every Web Service that is registered with the WSP system. Billing can be automated and sent to the subscribers periodically. Finally, service usage logs can be used to determine the quality of service (QoS) and hence the service level agreements (SLA).

Now let's look at how to build this system using the .NET Framework. I'm going to divide this task into two parts. First I'll build a generic provisioning framework, then I'll implement it for a real Web Service. I'm going to use C# for core classes (framework) and Visual Basic® .NET for implementation, and use a SQL Server 2000 database as the back end. In order to obtain the complete source code, please check the download for this article.

Building the WSP Framework

When I published a couple of Web Services on my online XML Web Services portal, I used to get a lot of SOAP traffic. Out of curiosity, I wanted to monitor the traffic, but I also wanted to limit some of the Web Services exclusively for my registered members. The WSP framework enables me to monitor and secure Web Services on my site using a process that is independent of my Web Services themselves.

The WSP framework has three architectural layers: the SOAP message interception layer (HTTP module), the SOAP message processing layer (WSP framework classes), and the data storage layer (SQL Server 2000).

SOAP Message Interception Layer

This layer consists of an HTTP module that intercepts every message received by the Web server. Since I'm only interested in SOAP messages, I need to distinguish them from all the other requests that are coming in.

In order to do this, I could just look for the SOAPAction header within the incoming message. Unfortunately, this method is not completely reliable because the SOAP specification makes a SOAPAction header optional.

There are two ways to handle this. I could look at the incoming HTTP request's target HTTP handler. As you probably know, HTTP handlers are responsible for processing the incoming HTTP Web requests. Each request type (or file extension) in .NET is mapped to a particular HTTP handler. The HTTP handler that handles requests to Web Services (ASMX files) is contained in the WebServiceHandlerFactory class, found in the System.Web.Services.Protocols namespace. So I will check for the HTTP handler's namespace to make sure it is being dispatched for a SOAP message (a Web Service request). Otherwise, I could check the file extension (.asmx) of the incoming HTTP request's URL.

Since I'm going to check for the HTTP handler, I need to do so after the handler has been dispatched for the current request. To do that, I need to wire up the onPreRequestHandlerExecute event, as shown here:

public class eSynapsHTTPModule : IHttpModule { public void Init(HttpApplication httpApp) { httpApp.PreRequestHandlerExecute += new EventHandler(this.onPreRequestHandlerExecute); httpApp.PostRequestHandlerExecute += new EventHandler(this.onPostRequestHandlerExecute); }

And the following code shows the onPreRequestHandlerExecute function itself:

public void onPreRequestHandlerExecute(object o, EventArgs ea) { HttpApplication httpApp = (HttpApplication) o; Type t = (httpApp.Context.Handler).GetType(); if((httpApp.Context.Request.ServerVariables["HTTP_SOAPACTION"] != null) | (t.Namespace.ToString() == "System.Web.Services.Protocols")) { //This is a Web Service, do processing

SOAP Message Processing Layer

This layer consists of a set of nine classes that examine the incoming messages and perform various activities such as authorizing access to the service as well as denying unauthorized access (for expired subscriptions, for example) and logging the service usage details. Although Figure 2 presents a simplified version of the actual framework process flow, it should give you a general idea of what functionalities the framework classes need to have.

Figure 2 Framework Process Flow

Figure 2** Framework Process Flow **

Here's some detailed information on the functionality and implementation for each of the classes:

User class This class represents both service providers and service consumers in the WSP system. Each User class instance will have a unique ID and a flag that indicates whether the user is a provider, consumer, or both. If a user is a service provider, each instance of that user will be associated with corresponding entries in the service catalog with service provision details. If a user is a service subscriber, each instance of that user will be associated with related Web Service subscription details.

Service class An instance of a Service class represents a published or provisioned Web Service in the WSP system. Each Service class instance is associated with a provider, instance of a user class, and any provision details. This class is used in both subscription manager and provision manager applications.

ProvisionModel and ValidProvision classes These two classes together define a provision detail for a published Web Service. A ProvisionModel class defines valid provisions that are allowed in the system. A valid provision model could take one of three forms: free subscription, pay-per-use, or lease based. The ValidProvision class assigns each published service a provision model and pricing model. The provision manager application and WSP runtime mostly use these two classes.

Subscription class This class represents an instance of a subscription contract of a service consumer. An instance of this class links a service consumer to a Web Service mapped to a valid provision model. This class exposes methods that are useful for saving and updating Service subscription-related data. This class is used by both provision manager and subscription manager classes.

ValidIP class This class, which is used in the subscription manager, exposes methods that are required to implement IP-level security for Web Services in the framework. A subscription class should have an associated ValidIP instance, meaning each subscription should be mapped to a valid IP address with which the service is going to be accessed. If an incoming request's IP address does not match the IP address that was specified at the time of subscription, the service access will be denied.

Indeed, you can provide security to your Web Service in several ways. One method is to add a SOAP header containing the consumer's identity and password. This method works, but you need to share the identity and password if there are multiple users accessing a subscribed Web service. Otherwise, you need to create a subscription instance for each user who is going to use the Web Service. In addition to that, you need to add processing in the Web Service client to add a SOAP header in every outgoing message. If you would like to avoid all these issues, IP- or domain-level security is a viable solution in a subscription-based Web Service.

Monitor class This is the only class that is accessed by the runtime application directly. The HTTP module creates an instance of this class for every incoming Web Service request. The Monitor class exposes functions that verify whether an incoming request is associated with a valid IP to access the Web Service. If an incoming request is a valid request with a valid subscription, the access to the service is granted and the usage is logged. If an incoming request fails to match the subscription or IP records, the Monitor class throws a SOAP exception with the appropriate error message.

This class uses the Service and ValidIP class. Figure 3 shows how the Monitor class works.

Figure 3 Monitor Class

public Monitor(string ServiceURL, string userIP) { ••• Service s = new Service(this.ServiceURL); if (s.ID > 0) { //This is a provisioned service //Check and see if this is a Valid IP to access this //Service ValidIP vip = new ValidIP(this.HostAddress, ServID); if(vip.ID > 0) { //This is a valid IP //Now check the Subscription Validity if(IsSubscriptionValid(this.ServiceID, this.UserID) { //Grant access to the service ••• } else { //Access to the Service Denied //Invalid Subscription //Throw an Exception ••• } } else { //Access to the Service Denied //Need to subscribe to access this service //Throw an Exception ••• } } ••• }

BillingModel and BillingData classes These two classes implement the billing process in the framework. The billing functionality is usually comprised of the process of analyzing the service usage data and calculating the bills based on the provision and subscription models. Since this functionality is totally business-dependent and varies from company to company, they have not been implemented. However, if you want to take a look, you can still find them in the framework with basic template code.

The classes I discussed in this section provide the core functionality of the WSP framework. The source code for these classes is available in the download. Later in this article, I will show you how to leverage these framework classes by implementing a WSP system.

Data Storage Layer

As mentioned, I've relied heavily upon SQL Server 2000 and T-SQL in the WSP framework. A fine tuning of the stored procedures and database tables (such as indexing) is required because the incoming Web Service requests are being intercepted and processed. Any compromise at the database end will reflect on the Web Service performance and hence on the quality of the service.

The partial database design for the WSP framework is shown in Figure 4. As you can see, the WSDiscover table is the centerpiece of the data model. This table stores the Web Service details and can be linked to the UDDI by using the column UDDIKey.

Figure 4 WSP Database Design

Figure 4** WSP Database Design **

In addition to this database schema, a set of stored procedures is in place to work with the framework classes. Most of them implement simple save, update, and retrieve functionalities (a complete list of stored procedures is available in the source code download). However, I would like to discuss the most important stored procedure, usp_WS_IsValidSubscription_Monitor, which is used by the Monitor class to determine the validity of the subscription.

Figure 5 shows part of the usp_WS_IsValidSubscription_Monitor stored procedure. As you can see, the logic discussed in the diagram in Figure 2 is partly implemented in this stored procedure. Mainly, the subscription validation check and service usage limit check are implemented here in order to gain overall system performance in the runtime.

Figure 5 usp_WS_IsValidSubscription_Monitor Excerpt

CREATE PROCEDURE usp_WS_IsValidSubscription_Monitor @ServiceID int, @UserID int AS --Takes Service ID and User ID as input parameters --Then issues a SELECT statement against WSSubscription Table ••• SELECT [ID], ProvisionID, ServiceUsageLimit, ServiceUsageAvailable, ServiceBeginDate, ServiceEndDate, ServiceUsageDeny FROM WSSubscription WHERE ServiceID = @ServiceID AND UserID = @USerID ••• --Check if the Service is denied by the provider --Or if the Subscription is cancelled IF (SELECT TOP 1 TServiceDeny FROM #eSynapsWSPFTemp) = 'Y' BEGIN SET @RESULT = -1 SET @ErrorMessage = 'Subscription Cancelled' END ELSE BEGIN -- Here check for the Available Usage Limit . . . IF (CAST(@Limit AS decimal)-CAST(@Used AS decimal))>0 BEGIN --Usage Limit is not reached --Then update the WSSubscription Table with --New Usage Limit . . . END ELSE BEGIN -- Set the error message SET @RESULT = -1 SET @ErrorMessage = 'Exceeded the usage limit' END END ••• SELECT @RESULT AS 'RESULT', @ErrorMessage AS 'ERROR'

Implementing the WSP System

Before I plunge into the implementation details of the system using the framework I outlined earlier, let's discuss a real scenario in which I need a WSP system and what I'm going to achieve with this implementation.

Suppose I have a Web Service which exists on my online XML Web Service portal. It allows users to search through my reference database for any Web Service-related topics. Anyone can type in the following URL (or create a Web Service client class using wsdl.exe) and access the Web Service at https://www.esynaps.com/WebServices/eSynapsSearch.asmx.

If I wanted to provide this Web Service exclusively for my registered members, I would need a solution that met several requirements. I should be able to prevent the general public from accessing the Web Service. My registered users, however, should be able to discover and subscribe to this service online. They should also be able to specify their own security credentials (IP address). That said, I should have the ability to deny the subscription, and my users and I should be able to verify the usage logs. Users should have the ability to subscribe to and cancel the Web Service whenever they want. Also, the solution should be generic enough for me to add and remove new services with ease. These requirements can apply to any Web Service whatsoever.

From the specifications I outlined, I need to implement the following applications: service provision manager, Web Service request interception, and service subscription management. I will review the implementation of each application. You can also take a look at an actual implementation of this system at https://www.esynaps.com/wsps.

Implementing Service Provision Manager

I have created a self-registration form for my users on eSynaps.com. When my users log onto the Web site, they will be presented with an option to register in the WSP system shown in Figure 6.

Figure 6 Self-registration Form

Figure 6** Self-registration Form **

Successful completion and submission of the self-registration form will create a new user in the WSP system. The code behind this page is shown in Figure 7.

Figure 7 Code Behind for Registration Page

Private Sub button_Click(ByVal sender As System.Object, ByVal e As _ System.Web.UI.ImageClickEventArgs) Handles button.Click Dim UId As Integer 'Create an instance of WSPF User class Dim objUsr As WSPF.User 'Then assign the values from the Form objUsr = New WSPF.User(CType(Session("WSUID"), Integer)) objUsr.Name = Name.Text objUsr.Company = Company.Text objUsr.CompanyURL = CompanyURL.Text objUsr.AddressLine1 = AddressLine1.Text objUsr.AddressLine2 = AddressLine2.Text objUsr.City = City.Text objUsr.State = State.Text objUsr.Zip = Zip.Text objUsr.Country = Country.Text objUsr.UserType = Type.SelectedItem.Value objUsr.BillModel = CType(Billing.SelectedItem.Value, Integer) 'Then call the save method UId = objUsr.Save() If UId > 0 Then 'Registration is successful Else UsrMsg.Text = objUsr.ErrorMessage End If End Sub

Upon completing the registration process the user should be presented with options based on their role in the WSP system. For example, a user who chooses to be a consumer should be given access to the subscription manager application. Similarly, a provider should be given access to the provision manager. If a user chooses to be both a provider and a consumer (as selected in Figure 6), they should be presented with both subscription and provision manager applications for their use.

Figure 8 User as Service Provider and Consumer

Figure 8** User as Service Provider and Consumer **

Figure 8 shows both the subscription manager and provision manager applications displayed for the user who is registered as both a service provider and a service consumer. As you can see, the provision manager has two options: "Publish a new service" and "Manage your Published Services."

Publish a New Web Service

Publishing a new service involves two activities. First, you need to specify the service description, network endpoint (ASMX file location), and Web Services Description Language (WSDL) contract location. Second, you have to assign a proper provision model for the service. Figure 9 shows the form that collects this information. As you can see from Figure 9, the service details and the provision details must be provided to publish the eSynapsSearch Web Service in the WSP system. The code that processes this form is shown in Figure 10. Figure 11 details the SaveService method.

Figure 11 SaveService Method

Private Sub SaveService() 'Setting the values for the Service class instance 'that is created in the above method oSer.ID = CType(ServiceID.Value, Integer) oSer.ProviderID = CType(Session("WSUID"), Integer) oSer.Name = ServiceName.Text oSer.Description = ServiceDesc.Text oSer.DiscoveryUrl = DiscoveryURL.Text oSer.ServiceUrl = UCase(ServiceURL.Text) oSer.HelpUrl = HelpDoc.Text oSer.UDDIKey = UDDIKey.Text oSer.ServiceBeginDate = System.DateTime.Now() oSer.ServiceEndDate = System.DateTime.Now() oSer.ServiceSuspend = ServiceSuspend.SelectedItem.Value 'Set the provision values oProv.ID = CType(ProvID.Value, Integer) oProv.ServiceID = CType(ServiceID.Value, Integer) oProv.ProvisionID = Prov.SelectedItem.Value oProv.UnitPrice = UnitPrice.Text oProv.Unit = "" 'Assign the provision object to the Service object oSer.Provision = oProv 'Save the Service object Call oSer.Save() If oSer.ID > 0 Then 'Successful save Else 'Error UsrMsg.Text = oSer.ErrorMessage End If End Sub

Figure 10 Code Behind Service/Provision Page

'Declare the Service and Provision objects Private oSer As WSPF.Service Private oProv As New WSPF.ValidProvision() . . . Private Sub button_Click(ByVal sender As System.Object, ByVal e As _ System.Web.UI.ImageClickEventArgs) Handles button.Click 'Then check if this service is already there.... oSer = New Service(ServiceURL.Text) If oSer.ID > 0 Then 'Error UsrMsg.Text = "This Web Service is already registered."_ & "Please try in Update mode." Else 'New Service—So save it. oSer = New Service() Call SaveService() End If End Sub

Figure 9 Specifying Service and Provision Details

Figure 9** Specifying Service and Provision Details **

Managing Existing Services

The second stage of implementing the provision management system is to provide the ability to manage the published Web Services. For that purpose, you can leverage the Service class from the WSP framework. Using a Service class, you can browse all of the published services and provide functionality to update the service. If you click the Manage link on the page, it will take you to the service publish/update screen shown in Figure 9.

Figure 12 Manage Web Service

Figure 12** Manage Web Service **

Here's the code behind the Manage Web Service page that is shown in Figure 12:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles MyBase.Load If Page.IsPostBack Then ••• Else ••• Call BrowseServicesByProvider() End If End Sub

The BrowseServicesByProvider method is shown in Figure 13. As its name implies, it lets you browse services by provider info.

Figure 13 BrowseServicesByProvider Method

Private Sub BrowseServicesByProvider() 'Declare a local Service class Dim oSer As New Service() Dim dr As SqlDataReader Try 'Browse the Services by user id—which defaults providers Call oSer.Browse(CType(Session("WSUID"), Integer), dr) 'Bind to the data repeater rp.DataSource = dr rp.DataBind() Catch e As Exception UsrMsg.Text = e.Message Finally If (IsNothing(dr)) Then Else dr.Close() dr = Nothing End If oSer = Nothing End Try End Sub

The Reports link allows you to see all consumers that are subscribed to the service. In my case, the screen in Figure 12 appears when I click the Reports link.

As you can see in Figure 12, there are three users subscribed to the Search Web Service. The options for the service provider on this screen include denying service for a particular user and viewing the usage logs. But before I move on to the usage logs, let's see what is going on behind the scenes.

In this ASPX page, I'm using the Subscription class. This method explains how to retrieve users based on a service subscription:

Dim dr As SqlDataReader 'Declare a Subscription class Dim oSub As New WSPF.Subscription() 'Then browse with Service ID for all the Subscriptions! Call oSub.Browse(CType(Request.Params("ServiceID"), Integer), _ Subscription.Type.ByService, dr) 'Then bind to the Data Repeater rp.DataSource = dr rp.DataBind()

Figure 14 MWSMonitor Table

Figure 14** MWSMonitor Table **

Now, let's look at the usage logs portion of the provision management application. When you click the Log link shown in Figure 12, you will see the screen shown in Figure 14. This page displays the contents of the MWSMonitor table. The codebehind for this page is shown here:

'Declare a WSPF Monitor object Dim oMon As New WSPF.Monitor() Dim dr As SqlDataReader 'Browse by Service ID and User ID oMon.Browse((CType(Request.Params("ServiceID"), Integer)), _ oSub.UserID, fromdate.SelectedDate.AddDays(1), dr) 'Bind to the Data Repeater rp.DataSource = dr rp.DataBind()

At this point I know that you're probably wondering, "how I got this data into Monitor Tables." The next section answers this question.

Web Service Request Interception

I have now successfully published a Web Service in the WSPS. But does that mean that the public's access to my Search Web Service is restricted? No. The process is not complete until you configure the Web Ser-vice request interception layer or the WSP runtime application.

As I discussed at the beginning of this article, the SOAP message interception layer (the HTTP module I designed in the first part of the article) does the actual security check and service usage metering and logging.

Figure 15 shows the implementation of the HTTP module. The onPreRequestHandlerExecute method is executed before the HTTP handler starts executing the Web Service.

Figure 15 HTTP Module Implementation

public void onPreRequestHandlerExecute(object o, EventArgs ea) { HttpApplication httpApp = (HttpApplication) o; Type t = (httpApp.Context.Handler).GetType(); 'If this is a SOAP Message if((httpApp.Context.Request.ServerVariables["HTTP_SOAPACTION"] != null) | (t.Namespace.ToString() == "System.Web.Services.Protocols") ) { 'Then create a Monitor object and check if the user is registered Uri url = (Uri) httpApp.Request.Url; WSPF.Monitor m = new WSPF.Monitor(url.AbsoluteUri, httpApp.Request.UserHostAddress); if(m.ServiceID > 0) { if(m.Valid) { 'A valid user, so save the begin time m.BeginTime = System.DateTime.Now; httpApp.Context.Cache.Add(String.Concat("monitor_esynaps_ws_", httpApp.Context.Request.GetHashCode().ToString()), m, null, System.DateTime.Now.AddDays(1), System.TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null); } else { 'Invalid user—Throw an Exception SoapException se = new SoapException(m.ErrorMessage.ToString(), SoapException.ServerFaultCode,httpApp.Context.Request.Url.AbsoluteUri); httpApp.CompleteRequest(); throw se; } } } }

The onPostRequestHandlerExecute method (see Figure 16) will be executed from the HTTP module when the HTTP handler finishes processing the Web Service. It calls the Save method on the Monitor class that was created in the method shown in Figure 15. When this function calls the save function on the Monitor class, the begin time and end time of the service request are saved into the WSMonitor table. That data is then used to generate the usage logs for the services.

Figure 16 onPostRequestHandlerExecute Method

public void onPostRequestHandlerExecute(object o, EventArgs ea) { HttpApplication httpApp = (HttpApplication) o; Type t = (httpApp.Context.Handler).GetType(); 'If a SOAP MEssage if((httpApp.Context.Request.ServerVariables["HTTP_SOAPACTION"] != null) | (t.Namespace.ToString() == "System.Web.Services.Protocols") ) { ••• 'Get the Corresponding Monitor object from the cache WSPF.Monitor m = (WSPF.Monitor) httpApp.Context.Cache.Get(String.Concat("monitor_esynaps_ws_", httpApp.Context.Request.GetHashCode().ToString())); if(m.Valid) { 'Set the end time m.EndTime = System.DateTime.Now; 'Save the Monitor Log m.Save(); } ••• } }

To be able to put this HTTP module to work so that it can intercept the incoming Web Service requests, you need to add the following configuration setting to your web.config file:

<system.web> ••• <httpModules> <add name="httpmod" type="eSynaps.WSPS.HTTP.eSynapsHTTPModule, _ eSynaps.WSPS.HTTP" /> </httpModules> ••• </system.web>

Now let's take a look at the state of the Web Service. When a user who did not register himself in the WSP system tries to access the Web Service, a SOAP exception will be thrown and a message displayed indicating that access to the Web Service is denied for unregistered users. Now the user will have to subscribe to this Web Service if they want to use it.

Service Subscription Manager

Upon receiving an error message (denying access to the service), a new user might log onto the site and subscribe as a consumer. A subscriber will have the option to subscribe to a Web Service or manage existing subscriptions. The subscription screen for the consumer uses the Service class from the WSP framework to display all available services. The user then views the details of the two available services and subscribes. The code for subscribing a new user to a Web Service is shown here:

'Declare a new Subscription class Dim oSub As New WSPF.Subscription() 'Set the values oSub.UserID = CType(Session("WSUID"), Integer) oSub.ServiceID = CType(ServID.Value, Integer) oSub.ProvisionID = CType(ProvID.Value, Integer) oSub.ServiceBeginDate = System.DateTime.Now() 'Set the Usage limit—some random number for testing oSub.ServiceUsageAvailble = 10 ••• 'And call Save! lSub = oSub.Save()

Once subscribed to the Search Web Service, the user has a usage limit of 10 hits. Next, the user will be presented with a screen to specify the IP address from which they are going to access the Web Service. Upon providing the right IP address and clicking the Submit button, the IP address will be saved in the WSP system tables using the ValidIP class from the WSP framework:

Dim oValidIP As New WSPF.ValidIP() ••• 'Set the Values oValidIP.ServiceID = CType(ServID.Value, Integer) oValidIP.UserID = CType(Session("WSUID"), Integer) oValidIP.IP = IP.Text 'Call Save lVIP = oValidIP.Save()

Now the user can access the Search Web Service 10 times.

What happens if this user tries to exceed the usage limit? On the eleventh request to this Web Service, access to the service will be denied. The Monitor class from the WSP framework will take care of the limit check. If the user still wants to use this Web Service, he has to renew the Web Service subscription.

Don't forget that the user also has access to the service usage logs in the Manage Subscriptions area. The service usage logs available for service consumers look just like the ones I showed in the provider's case.

Conclusion

The Web Services provisioning framework I built here is a powerful utility application that works well on a Web server. However, you can also implement the same system in an application service provider model by making the Monitor class remotable. You could try to expose the Monitor class as a Web Service, but remoting proves to be more efficient in this case. You could also implement your own security model and billing model in this system, to fit your particular needs.

Whether in a business-to-consumer case or in a business-to-business scenario, a properly designed Web Services provisioning system will allow Web Services to concentrate on the business processes and implementations rather than the infrastructural aspects of the Web Service technology.

 

For background information see:
The ASP Column: HTTP Modules
House of Web Services: The Continuing Challenges of XML Web Services

Chandu Thotaworks as a Technical Lead for a Chicago-based channel management software company. He has published several articles related to .NET. He is also a coauthor of the books Understanding the .NET Framework and Building an ASP.NET Intranet, both published by WROX Press.