Client/Server/Service pattern

Một phần của tài liệu SOA patterns (Trang 180 - 186)

It’s always nice to work on “green-field” projects because they have fewer constraints.

There are no existing systems that you need to work with or around. Most projects aren’t like that. You have systems in place and existing assets you need to integrate and work with. This is especially true for SOA projects, which are usually large transition projects that happen gradually over time—no one will stop the enterprise while you get the system ready to ship.

In the discussion of the Composite Front End pattern in the previous section, we looked at building a UI for SOA in a manner that’s akin to a green-field project, creat­

ing a new UI, from scratch to consume newly developed services. In contrast, the Cli­

ent/Server/Service pattern helps solve the problem of UI and SOA integration when you already have a working system in place and you want to evolve it to SOA.

As usual, let’s start with a scenario to get a better grasp on the problem.

PROBLEM

I worked on a project where the company had just finished converting its UI to a three-tier solution, based on Microsoft Silverlight connected to an application back end. Our team was tasked with building new services as well as replacing existing busi­

ness capabilities with new services that added additional functionality. To help compli­

cate things, the technology chosen for the new system was Java and related technologies. Figure 6.9 shows a simplified illustration of the problem.

On the left side of figure 6.9, you can see the current system, which has compo­

nents for single sign-on (SSO) and some business logic to handle customers, orders, and invoices. On the right side are the services that are going to be developed, with

155 Client/Server/Service pattern

UI (Silverlight)

Back end (IIS)

Database Single sign-on

Customers business logic

Orders business logic Invoice

business logic

Customers (REST on Finagle)

Sales reps (REST on Sinatra)

Orders (REST on Finagle)

Figure 6.9 A three-tier system that needs to integrate with new services.

Some of the capabilities of the three- tier system will remain intact (such as Invoice Business Logic), some will be migrated and expanded (such as Customers BL), and some new ones will be added (such as Sales Reps).

Orders and Customers destined to subsume and expand the current implementations and a new Sales Reps service that introduces new business capabilities.

Our “dream” solution might be to use the Composite Front End pattern (described in the previous section), where you have a portal-like UI that directly inte­

grates all the new services. This is possible if the current architecture and technologies of the current UI are compatible. In the project I’ve descried here, if the UI was based on Prism and the back end services were based on ASP.NET, it would have been possi­

ble to stitch the new services into the existing system. But most of the time that’s not the case, and you’re left with this question:

How can you connect an SOA to UIs where integration is problematic (for example,

? the client side isn’t SOA-aware or it uses incompatible technologies)?

We’ve discussed the possibility of not compromising on the UI for the services and of building the optimal service UI. Unfortunately this would require a major rewrite, and there would be a long wait before the business users could use the new capabilities (a long time to market). Not to mention that even in the simplistic example illustrated in figure 6.9, it’s likely that not all the existing functionality is planned to move to SOA in the near future, which can be another barrier for this kind of move.

Another option is to integrate the services within the existing UI. The main prob­

lem with that approach is that it’s hard to maintain a cohesive and unified user experi­

ence when you’re integrating two UI concepts together. The secondary problem with this approach is the difficulty of integrating technologies due to the different tools or skillsets of the services and UI developers.

SOLUTION

We need to find a way to integrate the new functionality, begin the SOA transition, and get a reasonable time to market. This is the answer in most cases:

Apply the Client/Server/Service pattern and use an intermediate server between

� the UI and the services.

The Client/Server/Service pattern, illustrated in figure 6.10, is a simple one. It sug- gests integrating existing UIs with new services on the server-side or back end of that UI. Essentially, on the server you’d have a service agent that represents the service.

The service agent includes a proxy that’s used for communicating with the services.

The existing service logic on the server must then be changed to integrate with the new service. The recommended way to do that is to change all the writers to write both to the existing implementation and to the new one, then get all the readers to read from the new implementation, and finally retire the old readers. This way, you can keep the application running and operational while you’re making changes.

“Wait a minute,” you might say. “How is that different or better than integration on the UI side?” The main reason integrating the new services on the server side is better is that the communications mechanism from client to server needs increased security as compared to server-to-server integration (inside the firewall). Switching security contexts and maintaining single sign-on can be tricky across technologies. Addition- ally, there is a wider selection of integration technologies for server integration than for client-to-server integration. Finally, when it comes to smart clients, there are even more reasons for server-side integration, such as the increased complexity of main- taining a uniform look and feel when integrating different architectures.

The Client/Server/Service pattern works well with the various service integration patterns (discussed in chapter 7) and it utilizes the message exchange patterns (see chapter 5). It can also make use of the Identity Provider pattern (see chapter 4) for passing the security context between the existing system and the new services.

Let’s take a look at how Client/Server/Service can be used to implement our example scenario.

Server

Service B Service agent

Proxy Service

interacon

Service A Business

logic

Server logic

UI

Other legacy systems Services

adaptor

Figure 6.10 The Client/Server/Service pattern integrates new services on the server side to minimize the impact on existing UIs and functionality.

157 Client/Server/Service pattern

TECHNOLOGY MAPPING

Implementing the Client/Server/Service pattern doesn’t require any specific technol­

ogy, although employing integration patterns can help. In particular, tools like ESBs (see the Service Bus pattern in chapter 7) can help weave disparate technologies and architectures together. Alternatively, you can integrate services and existing systems by building on simpler concepts like REST.

Let’s recap the example scenario. As illustrated in figure 6.9, there’s a Silverlight service in a classic three-tier setup, and you need to integrate it with a few new ser­

vices. This scenario identifies three new services: Customers, Orders, and Sales Reps.

Let’s look at a few code excerpts and see how you could introduce the Sales Reps ser­

vice into the existing system.

The first thing you need to change is the UI itself. Listing 6.5 shows a short excerpt from the ViewModel of the sales rep page in an MVVM Silverlight UI implementation.

NOTE In case you’re not familiar with Silverlight, Silverlight applications gen­

erally use a pattern called Model, View, ViewModel (MVVM). Listing 6.5 is an excerpt from the ViewModel component. See the further reading section for more information about MVVM.

Listing 6.5 Code excerpt with C# UI code calling to the server (via web service) public class SalesRepPageViewModel : INotifyPropertyChanged

{

private ISalesReps salesRepService;

private ObservableCollection<Employee> salesReps;

public ObservableCollection<Employee> salesReps {

get{return salesReps;}

set {

if (value != salesReps) {

salesReps = value;

RaisePropertyChanged("salesReps");

} }

} B WCF proxy

[Inject] to SalesRep

public PageViewModel(ISalesReps proxy) web service {

salesRepService = proxy;

salesReps = salesRepService.GetCurrentShift(); C Web service call }

}

You can see that the UI has a WCF proxy that exposes web services for the remote busi­

ness logic B. You can see the call to retrieve the sales reps on the current shift C.

The Sales Rep service, in contrast, uses a mix of a RESTful interface for setting and getting state along with AMQP queues to push events out to subscribers, such as the current shift is an event that’s pushed whenever a new shift starts. The following listing shows an excerpt of the Ruby code that handles subscription registration and allocates (binds) queues.

Listing 6.6 Code excerpt with a Ruby back end that handles the Sales Reps service class Sub < Sinatra::Base

def self.init

@@registered_queues={}

@@rabbit_wrapper=Bunny.new @@rabbit_wrapper.init

… end

put '/salesrep/subscribers/:name' do |n|

if not @@registered_queues.key?(n)

@@registered_queues[n]=@@rabbit_wrapper.allocate_queue n end

status 200

# return hyperlinks to subscriptions and subscribers...

end

get '/salesrep/subscribers' do puts "Subscribers list"

if not @@registered_queues.empty?

@@registered_queues.each { |queue| puts queue } end

end

post '/salesrep/subscriptions/:name' do |n|

request.body.rewind

values=request.body.read.split(",").each do |agent_id|

@@rabbit_wrapper.subscribe_topic n, Topic+sales_rep_id+".#"

end

status 201

#return ref to the subscription end

end

To tie the Silverlight (C#) code with the AMQP messages received, you can use a proxy on the business logic server that looks like a regular WCF service from one side, so that the Silverlight client can interact with it, and that also uses REST and AMQP to commu­

nicate with the service. The following listing shows an excerpt from the mediation code, written in C#, that creates subscriptions for changes in sales reps.

Listing 6.7 Excerpt from the Sales Reps service proxy on the back end service public static void Subscribe(string subscriberName, string s)

{

var addr = new Uri(HOST_URI, SUBSCRIPTIONS + subscriberName);

var req = CreateHttpRequest

159 Client/Server/Service pattern

➥(addr, new TimeSpan(0, 0, 0, 30), WebRequestMethods.Http.Post);

AddBody(req,s);

var response = CallApi(req);

}

public static void AddSubscriber(String subscriberName) {

var addr = new Uri(HOST_URI, SUBSCRIBER+ subscriberName);

var req = CreateHttpRequest

➥(addr, new TimeSpan(0, 0, 0, 30), WebRequestMethods.Http.Put);

var response = CallApi(req);

}

Naturally, there’s a whole lot more code involved to provide the actual interface, mediate between the service and the UI, and provide the business value. But the idea is that by utilizing the Client/Server/Service pattern, you can deliver the quality attri­

butes you need and get a working system.

QUALITY ATTRIBUTES

The main drivers for using the Client/Server/Service pattern aren’t technical. A pat­

tern like Composite Front End is a technically superior way to provide services with a UI. Nevertheless, when you want to migrate an existing system to SOA and you want to get a faster time to market, or when you don’t want to make minimal changes to an existing UI while introducing SOA, the Client/Server/Service pattern provides a good solution.

Table 6.3 provides two quality attribute scenarios for these two motivations.

Table 6.3 Client/Server/Service pattern quality attributes and scenarios

Quality attribute Concrete attribute Sample scenario Usability

Business drivers

Efficiency

Time to market

When the user needs to learn to use new features, the expe­

rience should be streamlined to ensure a minimal learning curve.

The time to market of new changes should be less than six months.

An additional reason for utilizing the Client/Server/Service pattern that isn’t directly related to quality attributes is the specialization of your development teams. If you have teams that are adept in different technologies, you may want to minimize the interfaces between the teams. Providing a centralized access point by using the Client/Server/Service pattern can help achieve that.

NOTE It’s important to remember that the Client/Server/Service pattern is usually a transient pattern. In these cases, it’s a stepping-stone that’s used while making the move to SOA from an existing system.

Một phần của tài liệu SOA patterns (Trang 180 - 186)

Tải bản đầy đủ (PDF)

(296 trang)