45 CASE STUDY:
A WEB HOSTING COMPANY

OBJECTIVE

We have discussed 42 design patterns in earlier chapters in different sections of this book. Now it is time for us to see how some of these design patterns can be applied together in building a software solution. The objective of this case study is to identify and apply some of the design patterns discussed in this book in developing a software solution for the business requirements of a fictitious Web hosting company, KPS Hosting Solutions.


KPS HOSTING SOLUTIONS: A BRIEF OVERVIEW

  • About KPS Hosting Solutions — KPS Hosting Solutions is a mid-sized Web hosting services provider based in the United States.
  • Customers — KPS has customers from the United States and Canada. KPS expects to serve customers from Asia as well in the near future.
  • Hosting packages — KPS currently hosts a few thousand Web sites and offers Web hosting on both Windows and UNIX platforms. KPS offers three different types of hosting packages — Basic, Premium and PremiumPlus — on both platforms.
  • Payment plans — KPS allows its customers to pay for the hosting services on a monthly, quarterly, half-yearly or annual basis using credit cards. KPS intends to accept checking accounts and personal checks in the near future.
  • Employees — KPS has both full-time and part-time employees. KPS guarantees an uptime of 99.99 percent to its customers. This requires some of the KPS employees to be available during night shifts.
  • Domain registration — KPS does not serve as a domain registrar on its own. KPS works with different domain registrars to register new domains or transfer existing domains. KPS offers this complimentary service based on customer requests.
  • Resellers — KPS attributes its fast growth to its committed, goal-oriented resellers. KPS classifies its resellers into two categories — Basic and Premium. Resellers with more than 100 domains are considered Premium resellers and receive a higher rate of commission.

REQUIREMENTS

Functional

  • Customer management — The system should have the ability to create a new customer profile, which includes the customer’s personal information, Web site(s) information and the payment information. The system should allow modifications and deletions of the customer profile. Whenever the customer address or the credit card information is submitted, the system should validate it before saving it to the database. Because KPS expects to serve customers from Asia in the near future, the system should be able to accommodate any enhancements specific to customers from Asia with minimum or no changes to the existing design or implementation.
  • Search management — The system should have the ability to search for customers, employees and resellers. Search results should be displayed with minimum details. The system should allow filtering from within the displayed search results based on user specified criteria. Upon selecting an item from the search results, a more detailed view of the selected item should be presented.
  • Billing — The system should have the ability to charge the billing amount of a Web site to the associated credit card. KPS currently accepts Visa, MasterCard, Discover and Diners Club. KPS bills direct customers, including resellers. Resellers are responsible for billing their customers.
  • Reports — The KPS management would like to see a set of predefined reports. In addition, the system should have an ad hoc report generation capability.
  • Employee management — The system should have the ability to create, modify or delete an employee profile.
  • Data migration — Currently, some of the tasks are accomplished using application software that is based on antiquated technology and is poorly architected. When the new system is built, data from the legacy system needs to be migrated to the new system. KPS intends to use the same data migration set up with minimum or no changes:
    • To migrate data from any other hosting firms it acquires.
    • To accept data from resellers (in case of bulk hosting requests) and move to the new system database.
  • Registrar interface — KPS would like to submit domain registration requests in a batch to domain registrars. These requests are normally sent to different registrars in the form of an XML string. The system should have the ability to generate and submit the request.
  • Reseller management — The system should have the ability to create, modify or delete a reseller profile. The system should provide the ability to calculate the commission to be paid to each reseller and generate checks to be mailed.
  • Trouble ticket management — All Web site related issues are first received by the tech support team that creates a trouble ticket for each reported issue. Within the KPS tech support, there are different service levels that are responsible for different areas of tech support. Once a trouble ticket is issued, it gets routed through these service levels until it gets resolved.

Technical

  • The overall system design should be component-based, manageable and reusable. System enhancements should be easy to apply.
  • The system architecture and design must make use of best design practices to optimize the system performance and maintainability.
  • Proper, consistent naming conventions must be followed.
  • Reuse of any existing or available software is encouraged. For instance, KPS has access to a Java class that validates a given Canadian address. But the interface provided by the class is not compatible with the naming conventions of the development team.
  • KPS Hosting Solutions currently uses only one database server with no secondary database server for fail-over. Sometimes the database server may be brought down for maintenance reasons. In the case of a new business request, if the database is down, the application should write the data to a flat file. The goal is not to turn down a customer request due to technical reasons. Because the customer information contains such sensitive data as the credit card information, the data must be encrypted before writing to the file.

BUSINESS OBJECTS AND THEIR ASSOCIATION

  • Whenever a new customer is created, the personal information is collected.
  • Whenever a customer requests hosting service for a Web site, the credit card information is collected from the customer and an account is created that allows the customer to access the Web site. Figure 45.1 shows the association of a Customer with other business objects such as CreditCard, Website, Account and Address.
i_Image11

Figure 45.1 Customer Association with Other Business Objects

i_Image1

Figure 45.2 Reseller Association with Other Business Objects

  • Whenever a customer contacts a reseller for hosting services, the reseller in turn contacts the KPS customer service for hosting the Web site. In this aspect, the system can treat resellers the same as a direct customer. Figure 45.2 depicts the association of a reseller with other business objects.
  • KPS offers Basic, Premium and PremiumPlus Web hosting packages on both the Windows and UNIX platforms. Figure 45.3 shows the representation of hosting plans in the form of a class hierarchy.
  • KPS provides tech support only for direct customers, not for those customers who have requested hosting services through a reseller. Resellers are responsible for providing billing and support services to their customers. Figure 45.4 depicts the relationship between a Web site and any associated trouble tickets.

FRAMEWORK FOR APPLICATION PROCESSING

As can be seen from the business requirements section, the application functionality consists of a set of services — customer management, search management, credit card services, address validation, employee management, etc. The overall application functionality may be modularized at two levels.


Enterprise Service Level

The first level of modularization can be accomplished at the service level. In other words, each of the services can be designed as an individual module. To provide client objects with a uniform interface to access these services, each service can be designed either as an implementer of an interface or as a subclass of an abstract or concrete class that declares the interface to be used by client objects. Figure 45.5 shows the design of different service modules as implementers of a common EnterpriseService interface.

i_Image1

Figure 45.3 Hosting Plan Class Hierarchy

i_Image3

Figure 45.4 Website–TroubleTicket-Employee Association

An enterprise service offers a group of related lower-level services to its clients. In other words, an enterprise service allows the processing of a set of related tasks. The terms “lower-level service” and “task” are used synonymously in this discussion. Each of the EnterpriseService implementers expects to receive a client request in the form of an XML request. One of the advantages of sending the request as an XML string is that it does not bind the client to a particular method signature on the service module. Another advantage is that it provides language independence. That means, clients and service implementers can be implemented in different programming languages and thus allow for the integration of legacy applications written in Fortran, COBOL, C++ and other programming languages.

i_Image1

Figure 45.5 Service Module Class Hierarchy with Each Module as an Implementor of a Common Interface

A service implementer is responsible for defining the required interface contract details to be used by different clients. This involves defining the request and the response structures for the service.


Generic Interface Contract

Request:


<ENT_SERVICE_NAME>
   <Task name='specificService'>
    <Input_1>abc</Input_1>
    <Input_2>xyz</Input_2>
       … 
       … 
    <Input_n>something else</Input_n>
   </Task>
</ENT_SERVICE_NAME>


Response:


   <ENT_SERVICE_NAME ErrorMsg=’N’>
     <RESPONSE>
       <Output_1>abc</Output _1>
       <Output _2>xyz</Output _2>
          … 
          … 
       <Output _n>something else</Output _n>
     </RESPONSE>
   </ENT_SERVICE_NAME>
or 
   <ENT_SERVICE_NAME ErrorMsg=’Y’>
     <ERRORS>
     <ERROR>
          <CODE>01</CODE>
          <MESSAGE> Error Message 1</MESSAGE>
       </ERROR>
         … 
         … 
         … 
       <ERROR>
         <CODE>0n</CODE>
         <MESSAGE> Error Message n</MESSAGE>
       </ERROR>
      </ERRORS>
   </ENT_SERVICE_NAME>
Where:

   <ENT_SERVICE_NAME> is the name of the enterprise service.
   <Task> is the lower level service offered by the service.

Sample Interface Contract

Request:


  <CREDIT_CARD_SERVICE>
    <Task name=‘validateCard’>
      <CardNumber>1234123412341234</CardNumber>
      <CardType>VISA</CardType> 
      <ExpDate>01-12-2008</ExpDate>
      <CardHolderName>CardHolder</CardHolderName>
    </Task>
  </CREDIT_CARD_SERVICE>


Response:


   <CREDIT_CARD_SERVICE ErrorMsg=’N’>
     <RESPONSE>
       <CardNumber>************1234</CardNumber>
       <Status>Valid</Status>
     </RESPONSE>
   </CREDIT_CARD_SERVICE>
or 

   <CREDIT_CARD_SERVICE ErrorMsg=’Y’>
      <ERRORS>
        <ERROR>
          <CODE>05</CODE>
          <MESSAGE>Unable to Connect to the Provider For 
   Verification</MESSAGE>
        </ERROR>
      </ERRORS>
   </CREDIT_CARD_SERVICE>

Whenever a client needs to access the services of an EnterpriseService implementer, it needs to:

  • Create an instance of the class representing the required enterprise service. The name of a service along with the corresponding implementation class can be specified using a Constant Data Manager.
  • Construct the service request as an XML string specifying the task name along with any data to be passed to the service as input as per the predefined contract.

Task Level

As mentioned earlier, an enterprise service component offers a set of related lower-level services (tasks). If the enterprise service module itself is made respon-sible for implementing these lower-level services, it could lead to a design that is very restrictive and hard to maintain. Whenever a new task needs to be added to the enterprise service or a task needs to be removed, it requires changes to the enterprise service module. To avoid these problems, an enterprise service module can be designed to make use of a set of predefined objects to handle the set of tasks that it is designed to process. The mapping between a lower-level task and its processor or handler can be specified in the form of an XML file.


Generic Task-Handler Mapping


   <TaskMappings service=’ENT_SERVICE_NAME‘>
     <Task name=’Task_Name’>
       <handler>package.class</handler>
     </Task>
   </TaskMappings>

Sample Task-Handler Mapping


   <TaskMappings service=’CREDIT_CARD_SERVICE‘>
     <Task name=’validateCard’>
   <handler>com.company.entservices.ccservice.CardValidator 
   </handler>
     </Task>
   </TaskMappings>

Whenever an enterprise service component is initialized, it needs to read the corresponding Task-Handler mapping into memory. Maintaining a separate Task- Mapping XML file for each enterprise service works better in an environment where individual teams are responsible for developing specific enterprise services modules. When a client request is received, the service component can check the mapping list to find the handler. Once the handler is found, the service component instantiates the handler class and submits the request XML file to it. To make it possible for all enterprise service components to treat all handlers in the same manner, every handler must offer the same interface for an enterprise service module to forward a client request. Towards this end, every processor class can be designed as an implementer of a common Interface (Figure 45.6).

A handler can in turn make use of other helper classes in accomplishing the task it is designed for. The mapping between a task and a handler is one-to-many. In other words, a handler may process more than one task. For every task that a processor processes, there must be a method with the exact same name as the Task name specified in the mapping XML file.

Defining a Task-Handler mapping does not completely prevent the enterprise service module from offering any services on its own. For instance, in the case of a small but highly useful service such as the AddressValidation service, it may not be required to designate a separate object to receive the client request. In such cases, the service provider may intend to process the service on its own with the help of other utility or helper objects. Such a service provider needs to implement a method with same name as the Task name. In addition, the Task-Handler mapping must specify the processor as itself.

Because each of the enterprise service components needs to provide the same implementation to read the corresponding Task-Mapping XML file, it is likely to result in duplicate implementation across enterprise service modules. To avoid this problem, the EnterpriseService can be designed as an abstract class with the implementation to read the mapping XML file into memory. This requires each of the service modules to be redesigned as subclasses of the Enterprise- Service class (Figure 45.7).

i_Image1

Figure 45.6 Client Accessing a Task-Handler Object

Throughout the life of the application there will be a need for only one copy of the mapping data and it needs to be available to all service modules and it should not result in any concurrency problems. To accommodate these requirements, when the mapping XML file is read, mapping details can be stored inside a Common Attribute Registry where each service can be treated as a CARGroup with Task-Handler values as individual name-value pairs within the CARGroup. This allows the storing of the same Task-Handler combination across multiple service modules.


Error Processing

The method signatures of both the service module’s execute() method and the handler’s process method indicate that they return a string back to the caller. Any errors that occur during the processing can be communicated back to the caller in the form of an XML string. The caller can parse the returned XML string to check for specific errors and carry out any required error handling.


Enterprise Services Design

In accordance with the application framework discussed earlier, every service module needs to define an interface contract to be used by the clients that intend to access its services.

i_Image1

Figure 45.7 Service Module Class Hierarchy with Each Module as a Subclass of a Common Parent Class


Address Validation

Using the enterprise services architecture discussed above, the address validation can be designed as a service module subclass of the EnterpriseServices class. Using the interface contract, clients can send the address to be validated to the service module. The service returns the validation results by way of the response structure defined in the interface contract.

When the service module receives a validation request, it can be forwarded to a designated handler, ValidationHandler instance. From the technical requirements section, it can be seen that there exists a utility to validate Canadian addresses that has a method name which is not in conformance with KPS IT standards. While it is possible to create an address validator for U.S. addresses with the method name following the naming standards, it may not be possible to alter the existing utility to validate Canadian addresses to follow the naming standards. Without having to recreate the utility from scratch, using the Adapter pattern, an adapter can be designed to make it possible to leverage the existing utility functionality. This same procedure can be used for validation of Asian addresses if there exists a predefined validation module that may not have a compatible interface.

The ValidationHandler can be designed to make use of a designated method to accept a country code and return the appropriate address validator. Once the validator is received, the handler can access its service in a seamless manner irrespective of the concrete class of the validator that is returned.


Credit Card Service

The two services that the credit card service offers are credit card validation and credit card charging. Let us design the credit card validation functionality here.


Validation

From the business requirements section, it can be seen that the system should have the ability to validate Visa, MaterCard, Discover and Diners Club cards. All of these cards have a definite set of steps in checking their validity. Some of the steps in validating these cards are identical across all these cards while some are carried out differently. Using the Template Method pattern, the outline of the validation steps and the common invariant parts of the overall algorithm can be kept inside an abstract class leaving the implementation of variant parts of the algorithm to its subclasses (see the example discussion in Chapter 38 — Template Method).


Search Management

The search management should allow users to search for resellers, customers and Web sites. For performance reasons only a limited set of search results are to be displayed on the screen. Such parameters can be specified using the Constant Data Manager. The necessary UI panel can be designed using the Builder pattern (see the example in Chapter 14 — Builder Pattern) where each concrete Builder is responsible for creating the necessary UI for allowing a user to specify the search criteria. This allows the same series of steps to construct the UI panel specific to a search type. This gives the flexibility to use the same UI building logic when a new search, say an employee search, is to be added to the system. Without altering the existing implementation, a new concrete Builder specific to the employee search user-interface can be designed.

One of the requirements is to select an item from the result set on the screen and view more details on the selected item. Whenever an item is selected, a database query can be executed to retrieve its details. One of the ways of improving the performance is to introduce some amount of caching where some of the most recently accessed item details are kept in the memory. This can be designed as an Object Cache using a Common Attribute Registry (see the example discussion in Chapter 29 — Object Cache). Whenever a search results item is selected to view more details, item details are fetched from the cache, if it exists. Otherwise, details are fetched from the database for display and are also stored in the cache for later access.


Customer Management

Let us design one of the important tasks to be supported by the customer management service, the creation of a new customer profile. From the business requirements section above, it can be seen that the application must function even if the database is down. This means that the application must have the ability to write to files as well as to the database.

The functionality to save data to a file and the database can be encapsulated in two different classes — FileManager and DBManager, respectively. To allow client objects to deal with both the FileManager and DBManager in a seamless manner, they can be designed as implementers of a common interface Persis-tenceManager to provide the same interface to its clients. By virtue of poly-morphism, client objects will be able to treat both the implementers as the PersistenceManager type.

Instead of having every client object to dealing with the choice of instantiating either FileManager or DBManager, the implementation of this decision logic can be kept inside a separate Factory Method. If there is a change in the way one of the PersistenceManager objects is to be selected, the Factory Method can be overridden in a subclass of the class that contains the Factory Method.

One of the important steps in creating a new customer profile is the selection of a hosting plan for the customer Web site. From the “Business Objects” section, it can be seen that there exist two families of hosting plans — Windows and UNIX. Instead of requiring client objects to be aware of the existence of the families of concrete classes (such as WinBasic, WinPremium,…, UnixPremium and UnixPremPlus) and have the knowledge of the concrete HostingPlan class to be instantiated, the Abstract Factory pattern can be used to encapsulate these details into a set of concrete factories that share a common interface. Clients can get access to an appropriate HostingPlan instance using the common interface without having to know the class type of the object returned.

In addition to the hosting plan selection, the customer profile creation involves address validation, credit card validation, account creation and saving customer data to the database or file. For address and credit card validation, the handler makes use of the AddressValidation and the CreditCardService enterprise services, respectively. While performing these lower-level tasks, the handler presents a very high level interface to its clients. In other words, client objects do not need to directly deal with the details of creating an account, validating addresses, credit card information and saving the data using an appropriate PersistenceManager. A client only needs to formulate its request to create a new customer profile in accordance with the interface contract defined by the CustomerManagement service and forward the request to the CustomerManagement enterprise service. In this aspect the handler functions as a Façade object.

The FileManager can be designed to make use of a utility to write data to the file. While designing the utility to write data to the file may seem like a trivial task, it requires special care to ensure that the utility functions as desired in a multithreaded environment. Applying the concept of the Critical Section ensures this by allowing only a single thread to access the utility method to write to the file. Such a utility can be used in other parts of the application for other purposes such as logging messages. From the requirements section, it can be seen that when the data is written to the file, it must be encrypted to avoid easy exposure. It may not be a good idea to alter the utility to implement the necessary encryption to the data being written. This is because encrypting the data before writing to a file may not be required everywhere the utility is used. As a work around, a Decorator object may be designed to provide the necessary encryption implementation before sending data to the utility to write to the file.


CONCLUSION

As part of the preceding discussion, we have designed:

  1. The address validation service
  2. The credit card service
  3. The new customer profile creation part of the customer management service
  4. The search management services

Interested readers may enhance the business requirements and design the rest of the system.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.41.205