close

Web services can be invoked statically using a WSDL service interface and service implementation documents, or dynamically by retrieving the service type definitions and the service implementation via UDDI. But until now, you couldn’t do both at the same time. You can now do this using the Model View Controller pattern (or MVC); this architecture supports both dynamic and static Web services. This article is primarily a design exercise and assumes that you know about design patterns and the MVC system. Please look to the resources to learn more about MVC.

The MVC paradigm is a way of breaking an application, or even just a piece of an application’s interface, into three parts: the model, the view, and the controller.

The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.

A view renders the contents of a model. It accesses enterprise data through the model and specifies how that data should be presented. It is the view’s responsibility to maintain consistency in its presentation when the model changes. This can be achieved by using a push model, where the view registers itself with the model for change notifications, or a pull model, where the view is responsible for calling the model when it needs to retrieve the most current data.

A controller translates interactions with the view into actions to be performed by the model. In a stand-alone GUI client, user interactions could be button clicks or menu selections, whereas in a Web application, they appear as GET and POST HTTP requests. The actions performed by the model include activating business processes or changing the state of the model. Based on the user interactions and the outcome of the model actions, the controller responds by selecting an appropriate view.
The MVC architecture has the following benefits:

  • Multiple views using the same model. The separation of model and view allows multiple views to use the same enterprise model. Consequently, an enterprise application’s model components are easier to implement, test, and maintain, since all access to the model goes through these components.
  • Easier support for new types of clients. To support a new type of client, you simply write a view and controller for it and wire them into the existing enterprise model.

An example of MVC in Web services Consider the example of a hosting site which finds the cheapest airfare between two destinations based on user queries. The hosting site looks up known Web services, which are registered in a Static Navigation Service file. This is a static look up of Web services, as the Web services interface and implementation are known to the system. The Static Navigation Service file is an XML file with entries like the following:

<service type=”CheapestAirFare” serviceimplemenation1=”http://airservice.com/rrpcrouter”
serviceimplemenation1urn1=”urn:fare” methodName1 =”getRate”
serviceimplemenationN= “”.. serviceimplemenation1urnN=”” .. methodNameN=”getCheapestRate”
dynamicLookup=”Yes”
nextscreenid= “CheapestAirFare”/>

The explanation of each entry is given below:

  • type (required): When the user selects a service, its type is set in a hidden parameter field which is passed to the controller servlet. The type which is set corresponds to the entry that is mapped in this file. This attribute is required, as our servlet dynamically creates and invokes Web services based on this parameter.
  • serviceimplemenation1: The first static service target URL where the first Web service is located.
  • serviceimplemenation1urn1: The first static service target URN (Uniform Resource Name). The URN uniquely identifies the service to the client.
  • methodName1: The method name to call the corresponding URN for serviceimplemenation1urn1.
  • dynamicLookup: There are two possible values — yes or no. A yes entry implies the performance of a dynamic lookup in UDDI for the corresponding service, while a no implies the opposite.
  • nextscreenid= (required): This identifies which screen should be invoked, based on the service type. This attribute is required as the servlet dynamically calls the corresponding screen based on this parameter.

The variable N defined in Static Navigation File above implies that there can be N service implementations providing the same Web service: This architecture invokes all of these services and consolidates the results of all the services for the user.


The architecture model The architecture can be visualized as the model presented in below Figure . MVC-SOA The graphic shows the interactions between the various components involved in this example, numbered according to the steps involved in the process of finding the cheapest fare. The table explains each of these steps in turn. Table 1: Process steps in the Cheapest Airfare application

Steps Explanation
1 The flat/thin client selects the required service which is being looked for — for example, cheapest airfare service between the UK and the US.
2 The servlet creates a new instance of the Service Manager and sends request and response objects to the Service Manager.
3 The servlet loads the static Service Mapping Navigator file, which contains definitions of service types (for example, cheapest airfare service), as well as the service provider and its urn. These services are static, as they are known to the system.
4 The Services Manager calls the corresponding formBean by instantiating the formBean factory. The formBean factory takes the service type from the http request parameter and calls the corresponding formBean. For example, if the service type is cheapestService, the formBean called is cheapestServiceFormBean. The corresponding formBean retrieves the user-entered query from the Httpservlet request parameter (for example, US and UK) and populates itself.
5 The Services Manager instantiates the corresponding ActionHandler depending on the service type and method name (N) using the ActionHandler Factory. For example, if the service type is cheapestAirFare and the method name is getRate, then the ActionHandler factory would instantiate cheapestAirFaregetRateActionHandler. For a corresponding service type, there can be many service implementations — hence there should be the same number of action handlers, since each may perform different logic. As for the return type, for some services this might be a simple string — for others it might be an XML document. So the corresponding action handlers must process those and ultimately return a common type — for example, a string. In this case, the string would represent a price such as $3000.
6 The Services Manager now invokes a method on ActionHandler, which performs various operations like invoking the SOAP Client and passing the required service implementor URLs, URN, and method name. The Services Manager is also responsible for placing the results it receives from the SOAP client into the common data — which contains the results from all of the action handlers. For example, the cheapest airfare for serviceimplemenation1urn1 would be $3000; for others it would be $3200, and so on.
7 The SOAP client communicates with the SOAP server and invokes the required services. This logic is part of each action handler.
8, 9, 10 This comes into play if the dynamic Web services lookup is enabled in the navigation file. The UDDI proxy communicates with the UDDI registry to find all business entities corresponding to the service name and find their service implementor’s URL, URN, and the corresponding method name to invoke — and then invokes the service utility class.
11 The service utility calls the SOAP client dynamically for each service implementation and passes the service implementation URL, URN, and method name. The service utility class is responsible for dynamically creating a SOAP request and getting the response back from the SOAP server.
12 The SOAP client dynamically communicates with the SOAP server and invokes the required services.
13 The Service Manager gets the next screen name from the Static Services Mapping Navigator file based on the current service type.
14 The ViewHandler factory calls the corresponding view handler based on the screen name.
15 The ViewHandler populates the view by retrieving data from the common data object.
16 If any system error occurs during the course of these activities,control will be passed to the error logger which redirects to the Error Page.
17 Finally, the data is displayed to the client.

The main advantage of this system is that this design is good for component-based development or for services where the overall architecture remains the same, and components can easily be plugged in. The listing below is some sample code of what an ActionHandler factory might look like. In this example, IActionHandler is an interface which is extended by all action handlers. Listing 1: Sample ActionHandler Factory

public class ActionHandlerFactory {

public IActionHandler getActionHandler(String serviceType ,
String methodName)
{
IActionHandler iaction = null;

try
{
String className = serviceType + methodName + “ActionHandler”;

iaction = (IActionHandler) Class.forName(className).newInstance();
}
catch (Exception e) {
e.printStackTrace();
}

return iaction;
}

}

Listing 2 below is a code snippet of how an action handler might look.

public class cheapestAirFaregetRateActionHandler implements IActionHandler {

public void performProcess(Formbean formbean, String serviceUrl,
String serviceUrn, String methodName, CommonData commonData)
{
//Type cast FormBean to current formbean i.e cheapestServiceFormBean
cheapestServiceFormBean chServiceformBean = (cheapestServiceFormBean) FormBean

//Get the destinations name from chServiceformBean

String country1 = chServiceformBean.getCountry1();
String country2 = chServiceformBean.getCountry2();

// Create and initialize the org.apache.soap.rpc.Call object.

Call call =new Call();

//Set the target URI .Method Name of service implementation1

// serviceUrn = urn:fare

call.setTargetObjectURI (serviceUrn );

// methodName=getRate
call.setMethodName (methodName );

Vector params =new Vector();

//Populate the parameter to be passed to soap server
Parameter country1Param =new Parameter(
“country1”,String.class,country1, “,Constants.NS_URI_SOAP_ENC);
params.addElement(country1Param);
Parameter country1Param =new Parameter(
“country2”,String.class,country2,Constants.NS_URI_SOAP_ENC);
params.addElement(country2Param);
call.setParams(params);
Response resp =null;

// Set the url of service implemenation1
// serviceUrl = http://airservice.com/rrpcrouter

URL url =new URL (serviceUrl);
// Invoke the corresponding service
Resp =call.invoke (serviceUrl, serviceUrn);

Parameter result=resp.getReturnValue();

//Get the result object from soap server
Object o = result.getValue();
// Do processing on result to get back the result in string ,
//and put the data in commonData
}
}

This completes the architecture for calling static and dynamic web services via the MVC Pattern. In the next blog, I would provide some implementation details to the MVC Pattern. Stay tuned.

This article of mine was first published by IBM DeveloperWorks.All rights retained by IBM and the author.

This is the first proposed architecture on Web services for dynamic orchestration using a MVC pattern. The article is cited in my patents as prior arts and used in many conferences. The article was published in June 2002.

Tags : Architecturefirst-articlesMVC SOAmvc-soa-classicSOA
Naveen

The author Naveen