Export (0) Print
Expand All
8 out of 9 rated this helpful - Rate this topic

Web Service Facade for Legacy Applications

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

patterns & practices Developer Center

Related Links

patterns and practices Developer Center

Web Service Facade for Legacy Applications

Naveen Yajaman, Microsoft Corporation; Josh Brown, Implement.com; Shanmugam Subramaniam, Tony John, Narsimha Reddy, and Venkataraman R, Digitial GlobalSoft (offshore division of HP); Andrew Mason, Microsoft Corporation

June 2003

Contents

Introduction
Web Services Facade Solution
Understanding the Adapter
Understanding the Web Service
Understanding the Sample Solution
Reference
Collaborators

Introduction

This guide discusses best practices for interfacing with legacy applications by using Microsoft® ASP.NET Web services and the Microsoft .NET Framework. The .NET Framework provides the foundation for creating a Legacy Application Interface solution using Microsoft technologies. This guide provides a sample solution using a Microsoft FoxPro® database as the legacy application and connecting it to a .NET-based application using ASP.NET Web services and SOAP. The specific technologies involved are ASP.NET, C# or the Microsoft Visual Basic® .NET development system, the .NET Framework, XML, Visual Basic, COM, and ADO.

Who Should Read This Guide

This document provides guidance to enterprise software developers and architects who provide interfaces to legacy systems using modern .NET solutions.

Interfacing with Legacy Applications

As your large enterprise grows, your IT challenges grow with it. Virtually all enterprises have legacy applications and databases, and they want to continue to use them while adding or migrating to a new set of applications that utilize the Internet, e-commerce, the extranet, and other new technologies. New platforms foster new technologies and capabilities. Rewriting legacy applications running on archaic systems to connect them to this new functionality is usually expensive and time-consuming.

In addition, as organizations expand and merge, their IT platform deployments often become fragmented. For example, different departments within an organization may use different applications and persistence mechanisms to access the same data. As a result, some data, such as customer information, may exist in multiple locations. The problems this can cause range from lack of efficiency (having to enter the same data multiple times) to inconsistency in data that is stored in different locations. Conflicting data stored in different locations results in higher operations costs, reduced customer satisfaction, and other negative impacts to an organization's bottom line. Having a unified view of all mission-critical data is beyond the capabilities of such a fragmented system.

This problem is not new. Connecting to your legacy applications saves the time and expense of having to migrate the legacy applications, and it provides a mechanism for tying together fragmented IT platforms. For years, IT departments have created point-to-point mechanisms, and middleware developers have written millions of lines of code for achieving interoperability of data sources and applications.

Benefits of Interfacing with Legacy Applications

Benefits of interfacing with legacy applications include:

  • Reduced IT costs due. Historically, most organizations have addressed interface challenges by writing large amounts of code. Employing well-designed solutions can reduce the initial financial and time outlays as well as the ongoing maintenance costs of this effort.
  • Reduced operational costs through more efficient value-chain processes. Automating key value-chain processes that reduce business process cycle times can reduce costs in many ways. For example, a more efficient supply chain can reduce the cost of carrying inventory.
  • Higher customer satisfaction and loyalty through new services and programs. Interface projects are essential for offering new information and business services more quickly than your competitors. For example, key online customer "self-service" operations function more easily when connecting the appropriate systems.
  • Better and faster business decisions. Aggregating business information and making it available in near-real time can fundamentally improve your ability to make better business decisions more quickly than your competitors can.

Past Solutions

Typical solutions use a combination of rewriting legacy code to run on more modern systems or installing so-called "middleware" applications to patch together disparate systems into a cohesive whole. There are significant downsides to both of these approaches. Rewriting legacy systems can amount to reinventing these systems from scratch. This can be extremely costly and sometimes result in solutions that are less reliable and cost-effective than the original. Patching together disparate solutions with middleware creates multiple points of failure and an overall system architecture so complex that increased maintenance costs can eliminate any benefit that the integration may have provided.

Ff648197.f01wsla01(en-us,PandP.10).gif

Figure 1. Past solutions architecture

In the type of solution shown in Figure 1, each application requires custom code to access the legacy application. Any changes in the interface exposed by the legacy application would require modifying each of the Client applications individually, multiplying the development effort required. If multiple programming languages exist within your Client applications, then development expertise in those languages will also be required. Some older applications use languages that have quite cryptic networking APIs, further hampering interface efforts. Because of scenarios like this, in the past, most attempts have resulted in point-to-point solutions that did not scale and were difficult to maintain. However, the widespread adoption of XML standards and Web services has made effective interfaces and integration more attainable.

When to Use This Guide

Figure 2 is a flowchart that describes various Enterprise scenarios. Follow the arrows to determine the best path to take in your integration efforts.

Ff648197.f01wsla02(en-us,PandP.10).gif

Figure 2. Solution flowchart

How to Use This Guide

This guide includes six sections. Following is a brief description of what each section contains.

Introduction

Discusses the purpose, scope, and audience of this guide.

Web Service Facade Solution Architecture

Explains the overall architecture of the solution, including design decisions.

Understanding the Adapter

Explains the purpose and functionality of the Adapter component and includes design decisions on how to create a custom Adapter to fit legacy applications.

Understanding the Web Service

Explains the purpose and functionality of the Web service.

Understanding the Sample Solution

Discusses the sample solution included with this guide, including design decisions. Also includes a guide to deploying the sample solution.

Reference

Provides a reference to database table schema and XML command formats used in the sample solution.

Web Service Facade Solution Architecture

This section describes the various elements that make up the architecture of the proposed Web service facade solution, as applied to the sample application included with this guide.

The sample Web service facade solution included with this guide accomplishes many of the goals of EAI without incurring the disadvantages of past solutions. This solution uses open standards to reduce the development and maintenance costs of an organization. By incorporating the latest patterns in distributed application design with the open standards of the Internet, this solution is able to achieve the best of both worlds.

Instead of rewriting legacy applications or customizing them with middleware to connect to other applications one by one, this solution entails creating a "facade" for the legacy application. Other applications are easily "plugged into" this facade. By modeling a legacy application into its basic functions of create, read, update, and delete (CRUD), and then exposing these functions through the HTTP communications protocol and an XML-based SOAP interface, the Web service facade solution allows other applications to access legacy data by making use of common Web services through standardized protocols. A consistent and simple interface with consolidated security makes for easier integration. This allows developers to focus on business logic rather than replicating existing functionality.

Ff648197.f01wsla03(en-us,PandP.10).gif

Figure 3. Architecture of the proposed solution

In the proposed solution, new client applications can interact directly with the Web service without making use of the Client Helper. Existing client applications can utilize the Client Helper to minimize the changes required for them to access Web services. Since the Client Helper is a .NET class, its use of the Web service is seamless and easy to implement. Also, accessing it is easy, and the skills required to do so would transfer to other development efforts within the Enterprise. Another primary advantage of this solution is that if a change occurs in the interface used to access the legacy application, only the Adapter would require modification. Isolating change and providing a simple common interface for all of your Client applications provides a major productivity benefit in your EAI development efforts. The possible limitation of this architecture is that such a simplified form of access may not support all of the functionality of more complex legacy applications.

Web Services Overview

In the past, distributed application design was limited: the protocols for interaction between components of an application were platform specific, proprietary, and difficult to use. The rise of the Internet and XML has made the potential of distributed computing a reality. Developers of Web services are able to focus on the business logic within their applications rather than on the tedious details of formatting, and of transporting data. Some of the benefits include:

  • Web services—Web services and supporting technologies including SOAP are quickly becoming the standard building blocks for modern distributed application design.
  • HTTP—The ubiquitous presence of HTTP makes it the obvious choice for a standardized communication layer through which components of a distributed application can interact. An HTTPS channel should be used for point-to-point secure communications.
  • XML—XML provides a platform-neutral format for data transfer and provides validation for content and structure
  • Secure Sockets Layer (SSL)—SSL provides data security using industry standard encryption protocols.
Note For more information about Web services, SOAP and the .NET Framework, see the "SOAP" section on MSDN® at: http://msdn.microsoft.com/en-us/library/ms995800.aspx.

Components of the Solution

The solution consists of the following components.

Client Application

The Client application can be any application that either creates an instance of the Client Helper class and calls one of the CRUD methods on that instance, or calls SOAP methods of the Web service to access the legacy application. The client either already takes advantage of Web services, or will be an existing client that requires modification. Because Web services are so easy to work with, extending most Client applications to take advantage of a Web service should require minimal development effort. If you cannot update your Client application, or if there are numerous disparate Clients that all require access to the Web service, it may make more sense to create a new Client application which replaces all of your current Client applications and which takes advantage of Web services.

Client Helper

Generally, newly developed Clients will directly access the Web service. If directly accessing the Web service is not an option, then use a Client Helper to facilitate interaction. The Client Helper is a .NET class that is instantiated by the Client, which subsequently calls the CRUD methods on that instance. The Client Helper handles the functionality of instantiating and making SOAP calls to the Web service. All of the functions within your Client that previously issued commands on a legacy resource will now be making simple method calls on the Client Helper

Web Service

The Web service handles SOAP requests and makes calls to the Adapter using the command factory pattern. The Web service also implements the parsing of command strings within the SOAP calls and performs the appropriate business logic in accordance with the nature of a specific request. A common interface exposed by the Web service contains the four actions common to data applications: create, read, update, and delete (CRUD). Mapping functionality to the CRUD interface may initially be complex, but reducing interaction with the legacy application to these four operations simplifies the rest of the picture immensely. Extensions to the basic functionality of create, read, update, and delete are also possible in the Web service.

Adapter

In those cases in which a legacy application does not expose a .NET accessible interface, you will need to build an Adapter that does have an accessible interface. The "Adapter" exists as an intermediary between the Web service and the legacy application. In a sense, the Adapter acts as a proxy on behalf of the Web service.

The Adapter models the data and functionality present in the legacy application and exposes an interface from which you can readily access this functionality. It does this by accessing the legacy application using whatever interoperability techniques are required. The Adapter also handles security issues and interaction with COM objects. This allows the Web service to remain independent of the legacy application, since the legacy application is modeled by the adapter.

Note For more detailed information about the Adapter component, see the "Understanding the Adapter" section. For more detailed information about the Web service component, see the "Understanding the Web Service" section.

Deployment Scenarios

The design decisions you make in deploying your Web service facade solution should take into account the unique needs of your organization. There are two main options for deploying your solution:

  • Single Tier Deployment Scenario—When your legacy application is based on the Microsoft Windows® operating system, and depending on your performance needs, it is possible to have the Adapter and Web service running on the same machine as the legacy application. This deployment architecture appears in Figure 4.

    Ff648197.f01wsla04(en-us,PandP.10).gif

    Figure 4. Single tier deployment scenario

  • Two Tier Deployment Scenario—If performance is a major issue, or your legacy application is running on an operating system other than Windows, you may wish to have a separate server to handle Web service requests. Your Web service may make use of multiple legacy applications that it integrates into a seamless whole. In the most complex scenario, there may be multiple Web services interacting with multiple legacy applications. This deployment scenario appears in Figure 5.

    Ff648197.f01wsla05(en-us,PandP.10).gif

    Figure 5. Two tier deployment scenario

In any scenario, you must also consider security. The more complex your system is, the more security concerns become an issue. Every additional point of isolation becomes a potential vulnerability that you must secure from intrusion.

Note For more information about Security, see the "Security" topic in the "Understanding the Sample Solution" section later in this document.

Understanding the Adapter

This section explains how to customize the Adapter component to fit legacy applications that do not expose a readily accessible interface.

Exposing Legacy Applications

When applying the Web service facade solution to a legacy application, ideally either the original application vendor or some third party has created an extension that allows you to access the legacy application through the .NET Framework. Usually these extensions come in the form of an update that exposes a common application programming interface (API). Unfortunately, sometimes the original vendor of a legacy application has ceased to exist, and support resources are difficult to find or not available. In these cases, it can be difficult to expose the application to .NET for the purposes of wrapping it in a Web service. Depending on the platform on which the legacy application runs, you will need either to migrate the legacy application, or create an Adapter, which adapts the legacy application in such a way that it is accessible from .NET.

Interfacing Scenarios

The method for interfacing with a legacy application depends on the form that particular application takes. Some of the primary ones are:

  • Legacy Application exposes a COM Interface:

    In this case, use COM interop to interact with the legacy application from the Adapter as demonstrated in the sample solution included with this guide.

  • Legacy Application consists of Dynamically Linked Libraries (DLLs):

    If all of the business logic of a legacy application exists within DLLs, then use .NET Platform Invocation Services from the Adapter to call C-style functions within the DLLs.

  • Legacy Application is a standalone exe application:

    It is possible to convert a standalone exe application into a DLL, which exposes it to other applications. Ideally, in this case you should consider migrating the application. Reasons for migration include:

    1. The application was probably designed for a single user and exposing it in a multi-user environment will have several issues including threading, state management, performance, and security to name a few.
    2. Most standalone legacy applications have inherent limitations working in a networked environment.
If migration is not an option, consider wrapping the unmanaged code using Managed C++ extensions. This makes exposure to a Web service easier and allows the legacy application to be migrated over time.

For more information about interface scenarios, see:

http://msdn.microsoft.com/library/en-us/vcmxspec/html/vcmg_overview.asp

http://msdn.microsoft.com/library/en-us/vcmxspec/html/vcManExMigrationGuidePart1_Start.asp

Implementing the Adapter

In creating an Adapter for your own legacy application, decide first how you want to be able to access that application and then design the interface of your Adapter around those goals. The interface of your Adapter should integrate seamlessly into the overall system architecture of your organization. If your Adapter exposes a logical interface, writing the code that accomplishes the details of those tasks on the legacy application should be clearer.

In the sample solution included with this guide, a COM object written in Visual Basic interacts with the legacy data. This solution is ideal because of the ready availability of an open database connectivity (ODBC) driver for the data format, as well as the interoperability between COM and .NET.

In a custom enterprise scenario, the goal is to find a way to expose the legacy functionality to something with which the .NET Framework can interact. Fortunately, .NET can access many types of code. If your legacy system is running on a Windows server platform, integration with .NET is easier. Many legacy applications have released updates that give them an API that is accessible from .NET. If the vendor for your legacy application has not provided such an update, there are often third-party interoperability extensions that perform the same function. Often these come in the form of COM objects, drivers, or code libraries that install on the same system as the legacy application.

For scenarios in which the legacy application is running on a non-Windows platform, there are often third-party migration tools that can assist in the process of migrating a legacy application to the Windows platform. If migrating your legacy application is not an option, and your legacy application connects to a network, then you can often access the application through a network sockets interface. In this scenario, the Adapter acts as a Client of the legacy application, using the legacy application's proprietary network protocol for interaction.

Note For more information about access to legacy APIs and integrating legacy applications, see "Integrate the Enterprise" at: http://msdn.microsoft.com/library/en-us/dnentdevgen/html/msdn_integr~1.asp.

Managing Transactions

Complex business components commonly contain a sequence of steps that occur as a transaction. These transactions usually involve one or more legacy systems. Multiple transactions may combine into one Logical Unit of Work (LUW).

An LUW must conform to the ACID requirements, which are as follows:

  • A for atomicity: An LUW is an atomic unit of processing; it completes in its entirety or not at all.
  • C for consistency: Valid execution of an LUW must take all involved resources from one consistent state to another.
  • I for isolation: Any updates to shared resources made within an LUW should be invisible to other transactions until the LUW is committed.
  • D for durability: Once updates made inside an LUW are committed, these changes must not be lost due to subsequent failures.

The concept of "rollback" is required to facilitate transactions. Issuing a rollback command will "undo" any previous modifications and effectively cancels a transaction that is in process. In the proposed solution, coordination of transaction processing should occur in the Adapter. Use a common transaction control manager such as COM+ for .NET components to manage transactions. Individual legacy systems may have their own transaction control systems with which the Adapter must interact.

Understanding the Web Service

Web services are fast becoming the standard component in distributed application architecture. This section describes the purpose and functionality of the Web service within the proposed solution.

The CRUD Interface

There are numerous standards for accessing applications. Developers have to learn vastly different methods for doing the same thing among different database vendors. A common way of dealing with this problem is to create a persistence layer within an application. This layer handles all of the operations that deal with the database, while exposing a simple and consistent interface to the developer of code that wishes to interact with the database. The vast majority of operations are simply different ways of applying the verbs "create", "read", "update", and "delete" to objects, entities or processes within the legacy application. This "CRUD" pattern is useful in simplifying access within enterprise application design. These four methods are the ones exposed by the Web service.

  • Create—Allows the insertion or creation of objects, entities or processes within the legacy application.
  • Read—Allows the retrieval of objects, entities or the status of processes within the legacy application.
  • Update—Allows the modification of objects, entities or processes within the legacy application.
  • Delete—Allows the deletion or termination of objects, entities or processes within the legacy application.

Implementation

Implementing the Web service in .NET means creating SOAP-accessible methods for create, read, update, and delete. These messages take string arguments. The contents of these strings are XML fragments in a proprietary format and that contain specific information about the entity upon which to act.

The purpose of the Web service is to receive SOAP requests from Clients and to respond by returning data in a proprietary XML format.

Note For more information about the XML schema used for commands and data, see the "Reference" section later in this document.

Customizing the Web Service and Adapter

In addition to the create, read, update, and delete functions, you may wish to extend the functionality of the Web service in numerous ways. One extension would be to create a function that returns all employees from a specific department. Another might be to provide the department ID for a given employee. These and other extensions are easily accomplished. When extending the interface, consider the most useful place for these additional properties and functions to reside. Making sure that your design decisions make sense from the perspective of the real world problem makes complex operations easier.

Following are examples of additional functionality your Web service may implement.

  • Example 1

    You want a function that returns the list of all employees within a department. Since employees belong to or are members of a department, it makes sense that the function that returns all employees within a given department should be within the Department class. You could call the function using the following syntax:

    myEmployeeList = Department.GetEmployees(departmentID)
      
  • Example 2

    You want to obtain the departmentID for a specific employee. Since the departmentID is a property of an employee, it makes sense to implement this as a property of the Employee class. You could then access the property in the following way:

    myEmployee.DepartmentID
      
  • Example 3

    You have a particular employee object and want to get a list of all of that employee's associates. You could issue the following method call:

    myEmployeeList = Department.GetEmployees(myEmployee.DepartmentID)
      
  • Example 4

    You want to change a batch of employees' zip codes all at once. You could issue the following method call:

    Department.SetZipCode(myEmployeeList)
      

    In example 4, myEmployeeList could be an XML fragment that contained multiple employee elements.

  • Example 5

    In some enterprise scenarios, there are independent applications that run as processes. CRUD operations may extend to apply to these processes. In this case, the CRUD operations would take on the following meanings:

    • Create

      Starts the process.

    • Read

      Queries for the status of the process.

    • Update

      Pauses and re-starts the process.

    • Delete

      Stops the process.

    Here we are treating the process as an entity that has an accessible state analogous to a data object entity. When interfacing with such a process using a web service, the point of interface is the shared I/O location; or, in the case when inter process communication is used, you will use an adapter. Microsoft BizTalk® Server and Microsoft Host Integration Server provide Web service adapters for many common enterprise processes.

    When starting the process, you could call the function using the following syntax:

    myProcess = MyServer.Create("My Process Instance")
      

    When querying the process for its status, you could call the function using the following syntax:

    myStatus = MyServer.Read("Name")
      

    When re-starting the process, you could call the function using the following syntax:

    MyServer.Update("Name", "New Name")
      

    When stopping the process, you could call the function using the following syntax:

    MyServer.Delete("New Name")
      

In general, when extending the Web service functionality, preserving the simplicity of the interface should drive your design decisions.

For more information about BizTalk Server Web service adapters for common business processes, see:

http://www.microsoft.com/biztalk/en/us/adapters.aspx

For more information about exposing existing code as a Web service, see "Exposing Existing Code as a Web Service Using the .NET Framework" available at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/bdadotnetwebservice1.asp

For more information about creating and deploying Web services using .NET, see "Getting Started with XML Web services in Visual Basic.NET and Visual C#" available at:

http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dv_vstechart/html/vbtchGettingStartedWithXMLWebServicesInVisualStudioNET.asp

Understanding the Sample Solution

This section provides a description of the sample solution that is included with this guide.

For purposes of demonstration, we create a legacy application in the form of a COM object, which draws data from files in a legacy format. The files are in FoxPro format, specifically FoxPro 2.6a. In order to access the data contained in the files, the legacy application uses Visual Basic. Visual Basic provides access to the data using a standard ODBC driver, which lets you create a System DSN to access the data. FoxPro uses a proprietary file format to store its data. Generally, there is one file per table in the database.

Note For more information about the table schemas in use for this sample, see the "Database Schema" topic in the "Reference" section later in this document.

The functionality of the legacy application is to receive commands from and return data to the Adapter using COM interop. The communication between the legacy application and the Adapter contains commands and results in a proprietary XML format. The legacy application parses this XML fragment and performs the requested operation on the legacy data.

The legacy application models the legacy data by providing create, read, update, and delete access to that data. This involves implementing create, read, update, and delete as methods in the legacy application so that they perform the desired data operations on the legacy data. To create this model, the legacy application implements the Model component of the Model-View-Controller (MVC) design pattern.

Note For more information about the MVC design pattern, see "Enterprise Solution Patterns Using Microsoft .NET" at: http://msdn.microsoft.com/en-us/library/ms998469.aspx.

Accessing COM from .NET

The legacy application is a Visual Basic COM object, whereas the Adapter is a C# .NET Framework application. COM interop allows the Legacy application to access the Legacy application.

Note For more information about COM interoperability, see "Introduction to COM Interop" at: http://msdn.microsoft.com/library/en-us/vbcn7/html/vaconIntroductionToCOMInteroperability.asp.

Security

Security for the FoxPro sample uses features included in version 1.1 of the .NET Framework. Version 1.1 of the .NET Framework allows system administrators to have fine-grained control over security policies for ASP.NET Web services. This allows you to grant code access permissions to specific assemblies within a Web application, restricting these assemblies to accessing specific resource types and performing certain privileged operations.

Included within the .NET Framework is the concept of trusted applications and code access security. By default, Web applications run with full trust. This allows them unrestricted access to any objects or functionality of the system upon which they run. Full trust applications may create and delete files, and may instantiate and invoke methods upon any classes present on the system. An application configured to run at a trust level other than full is a partial trust application. Partial trust applications have a restricted set of permissions, which limits their ability to access secured resources.

Isolating Security in the Sample Solution

The Adapter is a .NET class that has full trust on the server that is running the legacy application. The Adapter is the only Client of the legacy application, making the Adapter a convenient point at which to implement security in the sample solution. Thus, the Adapter is the point of isolation for securing the legacy application.

In order to accomplish this security, the Adapter verifies the permissions of any object that makes method calls on it using .NET code access security. To make the Adapter verify permissions, the sample solution makes use of a .NET custom permission. This custom permission grants access to the Adapter only to the Web service. The demand for custom permission prevents malicious code from making calls of the Adapter. Any attempt to call methods on the Adapter without having the correct permission will fail.

Using the Sandboxing Pattern

In the FoxPro sample, the Web service runs at medium trust. For security reasons, medium trust applications cannot instantiate or make method calls on objects written using unmanaged code. In addition, they cannot access the registry, event log, files outside of their application directory, or any other sensitive resources on the server on which they run. Since the legacy application is unmanaged, and the Web service requires access to it, a secure solution is desirable. In order to ensure the highest level of security for the legacy application, while also allowing the Web service access to the data and functionality it needs, an approach known as the Sandboxing Pattern is used.

The Sandboxing Pattern provides secure authenticated access to a protected resource. In this case, the legacy application is exposed but protected, and the Web service, which is running in a "sandbox," having been assigned a medium trust level, requires access to the legacy data. Code access security and a custom permission assignment accomplish this with the Adapter as the point of isolation.

The Adapter assembly is strongly named so that it receives appropriate code access security policy and permissions. Then it installs in the Global Assembly Cache (GAC). When the Web service makes a call into the Adapter, the facade demands the custom permission that the Web service possesses. The Common Language Runtime (CLR) verifies that the Web service and any callers of the Web service possess the custom permission by iterating through the stack that produced the method call. If the callers possess the custom permission, the Adapter uses the CodeAccessPermission.Assert method to permit the method call to an unmanaged object (the Adapter) from a managed medium trust caller (the Web service). Immediately after the call to the Adapter completes, the Adapter calls the CodeAccessPermission.RevertAssert method. The call to the legacy application completes within a try/catch block and the RevertAssert call is contained in the finally block.

All code that accesses protected resources is contained in the Adapter assembly. This assembly is strongly named so that it may install in the GAC. Only the administrator group of users can install assemblies in the GAC. Strong naming the Adapter requires that all of the assemblies that it references also be strongly named. To allow partially trusted callers (the Web service) to access the Adapter, add the following assembly level attribute to the Adapter:

[assembly: AllowPartiallyTrustedCallersAttribute()]
  

Install the Adapter in the GAC. This gives full trust to the Adapter, but not the Web service. The following code, which grants full trust to any assembly located in the GAC, is contained the custom ASP.NET medium trust config file created specifically for the sample solution.

<CodeGroup
   class="UnionCodeGroup"
   version="1"
   PermissionSetName="FullTrust">
   <IMembershipCondition 
       class="UrlMembershipCondition"
       Url="$Gac$/*"
       version="1"
   />
</CodeGroup>
  

More Information

For more information about Security and Web applications, see "Improving Web Application Security, Threats and Countermeasures–Chapter 9: Using Code access Security with ASP.NET" at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/ThreatCounter.asp

For more information about using code access security, see Chapter 8: Code Access Security in Practice and Chapter 9: Using Code Access Security with ASP.NET of Improving Web Application Security, Threats and Countermeasures at the following link:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/ThreatCounter.asp

Note: For more information on security, see "Improving Web Application Security: Threats and Countermeasures" available at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/ThreatCounter.asp.

Understanding the Client Application

For the purposes of demonstration, in addition to the sample Web service, this guide also includes an example Client written in C# that accesses the data in a legacy application. The Client uses the Client Helper, which in turn uses the Web service to access the Adapter and the data provided by the legacy application.

The example Client application has a simple interface to create, read, update, and delete employee and department details. This Client application sends commands as an XML string to the Client Helper. The Client Helper then wraps these strings in a SOAP method call to the Web service.

Note Because the included client application was created merely to show the sample Web service working, the client was not developed with error handling, data checking, or usability considerations. In addition, the client application and sample Web service do not perform any concurrency checking. The client application was designed to work with US English operating system settings.

When data returns from the Client Helper, it is in a predefined XML format.

After the user logs in, the interface to perform CRUD operations on employees appears (see Figure 6).

Ff648197.f01wsla06(en-us,PandP.10).gif

Figure 6. Interface to perform CRUD operations on employees

Table 1 lists the functionality provided by the Employee tab of the Enterprise Application Integration dialog box that is shown in Figure 6.

Table 1: Functionality of the Employee Tab in Figure 6

Button ClickedAction Performed
RefreshUpdates the list of all employees
NewCreates a new employee
ReadLoads data for the selected employee
EditLoads data for the selected employee for editing and saving
DeleteDeletes the selected employee
SaveInserts a new employee to the database or updates the data for the selected employee

Clicking the Department tab (see Figure 7) brings up a similar interface for performing CRUD operations on departments.

Ff648197.f01wsla07(en-us,PandP.10).gif

Figure 7. Interface to perform CRUD operations on departments

Table 2 lists the functionality provided by the Department tab of the Enterprise Application Integration dialog box that is shown in Figure 7.

Table 2: Functionality of the Department Tab in Figure 7

Button ClickedAction Performed
RefreshUpdates the list of all departments
NewCreates a new department
ReadLoads data for the selected department
EditLoads data for the selected department for editing and saving
DeleteDeletes the selected department
SaveInserts a new department to the database or updates the data for the selected department

This Client application is a thick Client developed using C# and NET Framework components.

Communication between the Client and the Client Helper uses XML in a predefined format. For details, see the "Reference" section later in this document.

Installing the Sample Solution

Installation of the sample installs the source code for the sample. You can use this source code as the starting point for a customized Web service facade for your legacy application.

The sample included with this guide has the following requirements:

  • Microsoft Windows 2000 or Windows XP
  • Microsoft Internet Information Services (IIS)
  • .NET Framework version 1.1
  • Microsoft Visual Studio® .NET 2003 development system
  • Visual Basic version 6.0

To install the sample

  1. Run the included EaiBlocks.msi file to place the source code and database files onto your system.
  2. Complete the following procedures.

To create user roles and accounts

  1. Create three Microsoft Windows NT® groups named Admin, HR, and Corp.
  2. Next, create users belonging to each of these groups.

These users and groups determine which of the CRUD operations they can perform on legacy data. Table 3 summarizes how the operations divide amongst the groups. The Adapter code enforces the permissions.

Table 3: Group Permissions

GroupOperations allowed on employee dataOperations allowed on department data
Human Resources (HR)CRUDR
Corporate (Corp)RUCRUD
Administrator (Admin)RUDRUD

To create a System Data Source Name (DSN)

Create a System DSN to point to the folder containing the database files installed by the setup program.

  1. On the Administrative Tools menu, point to Data Sources (ODBC), and then click the System DSN tab.
  2. In the Create New Data Source dialog box, click the Add button and then click Microsoft dBase Driver (*.dbf).
  3. In ODBC dBase Setup dialog box, in the Data Source Name text box, type EaiLegacyApplicationDsn.
  4. Clear the Use Current Directory check box.
  5. Click Select Directory and browse to the folder where the FoxPro tables are located. Your screen should look like the screen shot in Figure 8.

    Ff648197.f01wsla08(en-us,PandP.10).gif

    Figure 8. Creating a system DSN

  6. Click OK to save the System DSN.

To create the Web application

Note Both VB.NET and C# versions of the sample code are provided. Based on the language you choose, the source and binaries will be located either in the 'cs' or 'vb' subfolders.
  1. In Windows Explorer, right-click the folder <Installation Folder>\Code\cs\CrudBlock\EaiServices and select Properties.
  2. Select the Web Sharing tab and then select the Share this folder option.
  3. The Edit Alias dialog box will appear. In the Alias text box, type EaiServices.
  4. From the Administrative Tools menu, open Internet Information Services.
  5. Right-click the EaiServices virtual directory and choose Properties.
  6. Click the Directory Security tab and press the Edit button
  7. In the Authentication Methods dialog box, adjust the settings so that they match those shown in Figure 9.

    Ff648197.f01wsla09(en-us,PandP.10).gif

    Figure 9. Configuring Web service security

  8. Press OK to close the Authentication Methods window.
  9. Under Secure Communications click the Edit… button. For this option to be available, your server must already have an SSL certificate installed.
  10. Enable the Require secure channel (SSL) option. If you require 128 bit encryption, you may enable the Require 128-bit encryption option as well.
  11. Press OK to close the Secure Communications window.
  12. Press OK to close the EaiServices Properties window.
Note SSL cannot be enabled on the computer on which the solution is built. If you are building the solution on the Web server computer, you will need to first disable SSL, build the solution, and then re-enable SSL.

To build the solutions

Included with the installed source code are project files for Visual Basic 6.0 and Visual Studio .NET 2003.

Note Both VB.NET and C# versions of the sample code are provided. Based on the language you choose, the source and binaries will be located either in the 'cs' or 'vb' subfolders.
  1. Open the LegacyApplication.vbp file in the \Samples\CrudBlock\LegacyApplication folder and build the LegacyApplication.dll file using Visual Basic 6.0.
  2. Register the DLL with the following command: Regsvr32 LegacyApplication.dll.
  3. Generate a key with the following command: sn–k EaiKey.snk.
  4. Generate the signed interop assembly with the following command: tlbimp LegacyApplication.dll /out:Interop.LegacyApplication.dll /keyfile:EaiKey.snk.
  5. Generate the public key token and save for later use with the following command: sn–T Interop.LegacyApplication.dll.
  6. Open the CrudBlock.sln and make sure there is a reference to this newly created Interop.LegacyApplication.dll in the following projects:

    Code\cs\CrudBlock\Adapter

  7. Open the AppConstants.cs file under the project Code\cs\CrudBlock\CommonUtils. Update the member constant keyFile to point to the correct path the key generated in Step 3.
  8. Open the Web.config file under the project Code\cs\CrudBlock\EaiServices to the section <assemblies>. Update all of the PublicKeyToken values to the public key token generated from the signed assembly.
  9. Open the Web_mediumtrust_eai_crudblock.config file under the project Code\cs\CrudBlock\EaiServices and update only the PublicKeyToken value for SecurityClass Name="EmployeeInfoAccessPermission" to the public key token generated from the signed assembly.
  10. Open the CrudBlockTasks.bat in the installation folder and update all of the PublicKeyToken values with the new token generated.
  11. Build CrudBlock.sln using Visual Studio .NET 2003.
  12. Install the assemblies in Global Assembly Cache (GAC). You may run the CrudBlockTasks.bat for this.
    Note You must update the CrudBlockTasks.bat with the correct public key token. CrudBlockTasks.bat will look for assemblies in the release folder. If you are making a debug build, you must update the CrudBlockTasks.bat accordingly. You must also modify the CrudBlockTasks.bat depending on whether you are building the VB.NET or C# versions of the assemblies.

    The assemblies that install in the GAC are as follows:

    • Microsoft.ApplicationBlocks.CrudBlock.Adapter
    • Microsoft.ApplicationBlocks.ExceptionManagement
    • Microsoft.ApplicationBlocks.ExceptionManagementInterfaces
    • Microsoft.ApplicationBlocks.CrudBlock.CommonUtils
    • Microsoft.ApplicationBlocks.CrudBlock.EaiInterfaces
    • Microsoft.ApplicationBlocks.CrudBlock.EaiPermissions
    • Interop.LegacyApplication

    After you install assemblies in GAC, restart IIS.

  13. Build Samples.sln using Visual Studio .NET 2003.

To create the exception handling registry entries

  1. Start a command prompt.
  2. Change to the \Program Files\Microsoft Application Blocks for Eai\Crud Block folder or the folder in which you installed the sample solution.
  3. 3 Run the following command:
    regini.exe crudblockregentries.ini
      
  4. Close the command prompt.

Figure 10 shows the relationships between the source files included with the sample and the components of the solution architecture.

Ff648197.f01wsla10(en-us,PandP.10).gif

Figure 10. Relationship between the sample solution and the solution architecture.

After installing the solution, you may now start the sample client by running the generated Microsoft.Samples.CrudBlock.ClientApplication.exe. Login using the credentials you created when creating user roles and accounts.

Reference

This section provides a reference to database table schema and XML command formats used in the sample solution.

XML Schema for Commands and Data

The argument that passes to the CRUD methods is an XML string representing the entity upon which to act. Here is the XSD used for validating the command string:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="EAISchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
elementFormDefault="qualified">
  <xs:element name="Request" nillable="false" 
msdata:CaseSensitive="true">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Entity" type="xs:string" minOccurs="1" 
maxOccurs="1" nillable="false" />
        <xs:element name="Params" maxOccurs="1" minOccurs="1" 
nillable="false">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Param" maxOccurs="unbounded" 
minOccurs="1">
                <xs:complexType>
                  <xs:sequence />
                  <xs:attribute name="Name" type="xs:string" 
use="required" />
                  <xs:attribute name="Value" type="xs:string" 
use="required" />                  
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
  

Here are some examples of valid command strings:

  • Employee
    <Request>
    <Entity>Employee</Entity >
    <Params  >
            <Param Name='idemployee' Value='10' />
            <Param Name='vcname' Value='Jeff Smith'/>
            <Param Name='email' Value='someone@example.com'/>
            <Param Name='dob' Value='12/03/72'/>
            <Param Name='startdate' Value='12/03/72'/>
            <Param Name='managerid' Value='3'/>
            <Param Name='deptid' Value='301'/>
            <Param Name='levelid' Value='8'/>
            <Param Name='salary' Value='32000'/>
    </Params>
    </Request>
      
  • Department
    <Request>
    <Entity>Department</Entity >
    <Params>
            <Param Name='iddept' Value='100' />
            <Param Name='vcname' Value='eApps' />
            <Param Name='locationid' Value='1' />
    </Params>
    </Request>
      

When performing a read operation, data returns to the caller in the following format:

  • Employee
    <Response>
    <ReturnValues>
      <Item Name='idemployee' Value='100' />
      <Item Name='vcname' Value='David Smith' />
      <Item Name='email' Value='my-mail@mail.com' />
      <Item Name='dob' Value='12/03/72' />
      <Item Name='startdate' Value='12/03/72' />
      <Item Name='managerid' Value='3' />
      <Item Name='departmentid' Value='301' />
      <Item Name='levelid' Value='8' />
      <Item Name='salary' Value='3200' />
    </ReturnValues>
    <ReturnValues>
    ...
    </ReturnValues>
    </Response>
      
  • Department
    <Response>
    <ReturnValues>
      <Item Name='iddept' Value='1' />
      <Item Name='vcname' Value='Sales' />
      <Item Name='locationid' Value='8' /
    </ReturnValues>
    </Response>
      

Database Schema

Here are the column descriptions that describe the database used by the sample solution included with this guide.

Table 4: Employee Table

Column NameData TypeLength (in bytes)
idemployeeNumeric4
emailCharacter100
dobDate 8
startdateDate 8
manageridNumeric4
deptidNumeric4
levelidNumeric4
salaryCharacter8
vcnameCharacter100

Table 5: Dept Table

Column NameData TypeLength (in bytes)
iddeptNumeric4
vcnameCharacter100
locationidNumeric4

Table 6: EmpLevel Table

Column NameData TypeLength (in bytes)
idlevelNumeric4
leveldescCharacter200

Table 7: Location Table

Column NameData TypeLength (in bytes)
idlocationNumeric4
addressCharacter200

Table 8: DeptMgr Table

Column NameData TypeLength (in bytes)
deptidNumeric4
manageridNumeric4

Collaborators

Many thanks to the following contributors and reviewers: Mike Sherrill; Olivier D'Hose; Bala Balabaskaran; Fred Chong; Tim Shoultz; Sulabh Shrivastava; Rick Caudle; John Boylan; Andy Dunn.

Thanks, also, to the Prescriptive Architecture Guidance and content team: Edward Lafferty, Matt Evans, Chris Sfanos, Sandy Khaund, Pat Collins (Entirenet), Soumya Nandy (Satyam Computer Services Limited), Amith Ellur (Satyam Computer Services Limited), Nisar Ahmed (Satyam Computer Services Limited), Ismail Khalifullah (Satyam Computer Services Limited), Sridhar Rajaram (Satyam Computer Services Limited), Soumya Nandy (Satyam Computer Services Limited).

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.