Service-Oriented Modeling for Connected Systems: Part 2

 

by Arvindra Sehmi and Beat Schwegler

Summary: As architects, we can adopt a new kind of thinking to essentially force explicit consideration of service model artifacts into our design processes, which helps us identify the artifacts correctly and at the right level of abstraction to satisfy and align with the business needs of our organizations. In Part 1, we offered a three-part approach for modeling connected, service-oriented systems in a way that promotes close alignment between the IT solution and the needs of the business. We examined the current perspective of service-orientated thinking and explained how the current thinking and poor conceptualization of service orientation has resulted in many failures and generally poor levels of return on investment (ROI). We also examined the benefits of inserting a service model in between the conventional business and technology models that are familiar to most architects, and discussed the Microsoft Motion methodology and capability mapping to identify business capabilities that can be mapped to services. In this second of two parts, we'll show you how to implement these mapped services.

Contents

Creating a Technology Model
Creating Services Today
Six Steps for Building a Service
Using Process-Automated Guidance
Acknowledgements
About the Authors
Resources

In Part 1, we ended our discussion with a pragmatic Service Oriented Analysis and Design (SOAD) process that is used to extract all of the necessary pieces required to build your service model. This extraction includes service contracts, service-level agreements (SLAs) derived from the service-level expectation (SLE) defined for each business capability, and the service orchestration requirements. With a detailed service model closely aligned with and derived from the business model, you should now be well placed to map the service model to a technology model that identifies how each service will be implemented, hosted, and deployed.

By using the preceding approach and by creating the service model, you can hand over to your IT department data schemas, service contracts, and SLA requirements. Before the service is built, however, consideration should be given to supporting service autonomy at the technology level by clearly separating interfaces from implementation and the underlying transport mechanisms. Developing service implementation strategies that decouple the service endpoint from the service implementation helps you to plan for change. Selecting appropriate hosts and service management options to fulfill the stated SLAs also requires careful consideration. Your choices in these areas are captured and defined by the technology model.

Creating a Technology Model

The technology model consists of several artifacts: service interface, service implementation, service host, service management, and orchestration engine. We will look at the details of each.

The service interface specifies how a document or message can be received. The interface allows you to specify which transports are going to be provided, regardless of the implementation. More than one service interface can implement a service contract, but every service interface implements one specific binding such as SOAP over HTTP.

If required you can provide multiple service interfaces using different transports. For example, you might bind a single interface to a Web services transport and also to a Windows message-queuing transport. Each transport provides different capabilities such as interoperability and transactional support and different restrictions. For example, message queuing does not directly support the request/response pattern. At least one interface should be provided for interoperability by ensuring that the interface conforms to the Web Services Interoperability Basic Profile (WS-I BP) version 1.x.

Service implementation is the implementation of a business capability independent of the underlying host. It should also have no dependency on its interfaces. The service implementation can call other services by using binding-dependent proxies, and to achieve binding-independent proxies they should be created by using factories.

The service host provides an endpoint for the service interfaces. The choice of host should be based on specified SLA requirements. For example, if the business expects 24/7 operations, this characteristic has a huge impact on your choice of host, and in these scenarios queuing technologies such as Microsoft Message Queue or SQL Server Service Broker are often required. In the technology model hosts represent cost options. In the business model the SLE represents the value. By being able to map the choice of host back to an SLA captured by the service model, and ultimately to a business-driven SLE, the cost of a given host can be justified and quantified.

An added benefit of moving to services and away from silo-based applications is that if you have one specific business capability that requires 24/7 operations, you can move this service to a host that provides the necessary performance and redundancy. You might be able to use less-costly hosts for other capabilities. With the silo-based approach, you are forced to select one host for the entire application.

For the service management artifact appropriate action must be taken if an SLA cannot be fulfilled, and to support this action you must be able to monitor and manage the service. Service interfaces, implementations, and hosts should be instrumented, for example, by using Windows Management Instrumentation (WMI). Microsoft Operations Manager (MOM) can then be used to monitor and manage the service, while Microsoft Systems Management Server (SMS) is used to support change and configuration management in the service's "edge" ecosystem. Your chosen orchestration engine should also provide monitoring support such as the Business Activity Monitoring (BAM) features provided by BizTalk Server. In the future, WS-Management will play a central role in managing resources independently from the hosting and management platform.

For the orchestration engine artifact orchestration requirements should be defined in a platform-independent way by the service model, but ultimately you need to use a specific orchestration engine. The technology model identifies the target platform such as Microsoft BizTalk Server.

By creating the technology model you can explicitly capture the foregoing artifacts, but how should you approach service development? How do you map these artifacts to a service implementation, and how do you implement the contract specified by the service model? Shortly, we will discuss an approach that helps you to build services in a way that satisfies the service tenets and modeling principles discussed earlier.

Creating Services Today

Given a set of conceptual service artifacts, how can you define these in code, and how should you organize the code within Visual Studio 2005? The key thing to bear in mind is the need for separation among data, messages, interfaces, implementation internals, and transport bindings. Figure 1 shows an approach for mapping service artifacts to Visual Studio 2005 solutions and projects.

The "xx" placeholders shown in Figure 1 represent an appropriate namespace based on the service name—for example, OrderService. Using a single Visual Studio 2005 solution file for a given service and as a container for the multiple projects you see in Figure 1 is a recommended practice. We will look at these projects.

  • The xx.Data project is used to hold the on-the-wire data schema definitions that are obtained from the service model entity and also contains the common language runtime (CLR) representation of that schema.
  • The xx.Messages project is used to hold definitions of the messages required to communicate with the service, which includes inbound and outbound messages. A message is represented as a schema element containing elements of the data contract.
  • The xx.Interfaces project contains the interface definitions.
  • The xx.ES and xx.WS projects contain transport endpoints for interfaces. In the example shown in Figure 1, xx.ES provides an enterprise services transport, and xx.WS provides a Web services transport.
  • The xx.Adapters and xx.Internals projects contain the implementation of the service. An adapter contained in the xx.Adapters project provides a level of indirection between the interface and the internal implementation. The adapter parses the inbound message and passes the relevant data entities to the internal implementation code. The adapter also wraps data output from the implementation within the response message. Note that with this approach, the implementation knows nothing about the messages passed through the interface, which allows you to change your messaging infrastructure without affecting your internal service implementation.

Click here for larger image

Figure 1. Mapping service artifacts to Visual Studio 2005 projects (Click on the picture for a larger image)

The endpoint shown in Figure 1 is purely a deployment artifact and is dependent on your choice of transport binding. For example, with a Web services transport, you would deploy your service to an Internet Information Services (IIS) Web server running ASP.NET.

Adapters. The adapter is a key artifact that enables you to decouple your implementation from the messaging. It is also a good place to perform message transformations if they are required. For example, within the adapter you could transform an external representation of a customer ID (for example, 10 characters) into your internal representation (for example, 12 digits). By creating a new adapter per version of your service, the adapter also provides a way to version services without affecting the implementation or your previously published service interfaces.

Versioning. When considering versioning, you need to distinguish between versioning the abstract or concrete contract and versioning the internal implementation. A key architectural goal is to provide independent versioning between the two. The contract itself consists of the data, message, interface, and endpoints. You can version each of these artifacts independently if you architect the service so that each composing artifact refers to a single version of the composed artifact. For example, the message contract that is composed of the data contract should refer to precisely one version of the data contract. This reference must be true for the XSD/WSDL and the CLR representation of that contract.

Data and message contracts should be versioned according to the XML versioning and extensibility policy (see Resources). You can version service interfaces by providing a new interface that inherits from the previous (CLR), one that is mapped into a new WSDL port type.

Six Steps for Building a Service

To arrive at these Visual Studio 2005 projects and build a service today using this approach, adopt this six-step process:

  1. Design the data and message contract.
  2. Design the service contract.
  3. Create the adapters.
  4. Implement the service internals.
  5. Connect the internals to the adapters.
  6. Create the transport interfaces.

Let's look at the details of each step. For the first step—design the data and message contract—take the canonical data schema that defines the wire representation of the data (an output of your service-oriented analysis and design) and define the data classes and message classes. There are two approaches to creating your data schemas and data classes. By using a schema-first approach, you can create an XSD schema and then use a tool such as Xsd.exe or XsdObjectGen.exe to generate the data classes automatically. Alternatively, if you prefer a code-first approach, you can define your data classes in C# or Visual Basic and then use Xsd.exe to create an equivalent XSD schema. Here is an example of a data contract.

namespace DataContracts
{
     [Serializable]
     [XmlType("Order", Namespace=
           "urn.contoso.data/order")]
     public partial class Order
     {
           [XMlElement("Customer")]
           public Customer customerField;
           [XMlElement("Items")]
           public OrderItemsList
                ordersItemsField;
           ...
     }
}

Once you have defined your data classes, you can define your inbound and outbound messages, which contain the data classes as their payload. For example, this code snippet shows an input message called OrderMessage for a hypothetical order service that contains an Order as its payload.

namespace MessageContracts
{
     using System.Xml;
     using System.Xml.Serialization;
     using DataContracts;
     [Serializable]
     [XmlType(Namespace=
           "urn.contoso.msgs/orderservice"
           )]
     [XmlRoot(Namespace=
           "urn.contoso.msgs/
          orderservice"]
     public class OrderMessage
     {
           [XmlElement("Order")]
           public Order order;
     }
}

In step 2—design the service contract—define the abstract service contract either by using a WSDL-first approach or by defining your interfaces using C# or Visual Basic. Your interfaces define which messages your service receives and which messages (if any) it returns. To generate the interface from the WSDL, you need to use the Wsdl.exe /si switch.

Wsdl.exe xx.wsdl /si

Note that this switch works only with Microsoft .NET Framework version 2.0. This next example defines an interface to the order service that defines a single PlaceOrder() method that accepts an OrderMessage message and returns an OrderTrackingMessage message.

namespace Interfaces
{
     using MessageContracts;
     public interface IOrderService
     {
           OrderTrackingMessage
                PlaceOrder(OrderMessage
                placeOrderMsg);
     }
}

Note that in this case a request/response message pattern is used, and therefore you need to ensure that the message processing time (the time between the request and response) must be sub-second. If this processing time cannot be guaranteed, use another message-exchange pattern such as a duplex message exchange, which correlates two one-way messages to a logical request/response pattern.

To generate the WSDL from the preceding interface, you can create an ASMX Web service class that implements the interface and then calls the Web service passing ?WSDL—for example, https://localhost/OrderService/OrderService.asmx?wsdl. This Web service causes the WSDL to be generated and returned from the Web service.

Listing 1. The |OrderService interface

namespace Endpoints.WS
{
    using System;
    using System.Diagnostics;
    using System.Web.Services;
    using System.ComponentModel;
    using
System.Web.Services.Protocols;
    using
System.Web.Services.Description;
    using System.Xml.Serialization;
    using MessageContracts;
    using ServiceInterfaces;
    using Adapters;
    [WebService(Namespace=
       
"urn.contoso.interfaces/
orderservice")]
    public class OrderService :
System.Web.Services.
        WebService, IOrderService
    {
        [WebMethod]
        [SoapDocumentMethod(ParameterStyle=
            SoapParameterStyle.Bare)]
        public OrderTrackingMessage
PlaceOrder(
            OrderMessage
placeOrderMsg)
        {
            IOrderService adapter
= new OSA();
            return
adapter.PlaceOrder(PlaceOrderMsg);
        }
    }
}

In step 3—create the adapters—create the adapter class that provides the indirection between the interface and the internals. This class ensures that the internals knows nothing about the message contract. The adapter unwraps the inbound message and passes the payload data to the internal implementation performing any required data format transformations from message to internal format. Similarly, on the way back the adapter performs any necessary format transformations on the data returned from the service implementation and wraps it inside an outbound service message if there is one. Here's a sample adapter.

namespace Adapters
{
     using MessageContracts;
     using ServiceInterfaces;
     public class OSA : IOrderService
     {
           public virtual
                OrderTrackingMessage
                PlaceOrder(
                OrderMessage placeOrderMsg)
           {
                // Call internals here
           ...
           }
     }
}

Note that the adapter is always in process with the caller, and the process identity depends on your choice of host. If the internal implementation is hosted within IIS, then the ASMX ("edge") interface instantiates the service internal. If the internal is hosted within enterprise services, but the calls arrive through an ASMX Web service, the ASMX interface delegates the call to the enterprise services interface, which then instantiates the adapter and passes the message to it. Because all transports implement the same interface you can chain calls together.

In step 4—implement the service internals—create your service internal implementation. A single implementation exists regardless of your chosen transport or transports. This code snippet shows the skeleton code required to provide an implementation of the order-processing service.

namespace BusinessLogic
{
     public class OSI
     {
           public static string
                AcceptOrder(
                DataContracts.Order order)
           {
                // Process the order
                ...
                return "XYZ";
           }
     }
}

Notice how the internal implementation has no knowledge of the message. It knows about only the data contract. In this case it is passed a single Order object. If you want to be completely independent of the wire format, the internal would not even have access to the data contract. In this scenario, the adapter would map the external data contract to the internal data types.

In step 5—connect the internals to the adapters—call your internal implementation from your adapter code. Note that the message is not passed to the implementation, which decouples the internal implementation from the message contract and enables you to change one without affecting the other. This code snippet shows the adapter code again, this time with a call to the internal service implementation.

namespace Adapters
{
     using MessageContracts;
     using ServiceInterfaces;
     public class OSA : IOrderService
     {
           public virtual 
                OrderTrackingMessage
                PlaceOrder(
                OrderMessage placeOrderMsg)
           {
                OrderTrackingMessage otm =
                     new OrderTrackingMessage();
                otm.TrackingId =
                     BusinessLogic.OSI.
                     AcceptOrder(
                     placeOrderMsg.Order);
                return otm;
           }
     }
}

In step 6—create the transport interfaces—bind your abstract service interfaces defined in step 2 to a specific transport. Listing 1 shows the IOrderService interface defined in step 2 bound to a Web services transport.

Using Process-Automated Guidance

By following the six-step process just discussed, you can build services that conform to all tenets and principles covered here. However, because all of the items described in the six-step process can be described by metadata, it is possible to automate large sections of the service generation. You can use tools such as the Guidance Automation Toolkit (GAT) to help automate the guidance (see Resources). Process-automated guidance is particularly helpful to transform between semantically identical XML and CLR artifacts such as XSD and CLR classes, transform among the WSDL port type and CLR interfaces, generate adapters based on the interface description, and generate different endpoint technologies based on the interface description.

The old way of thinking about service orientation is not working, and a new way of thinking is required. By adopting this new kind of thinking, as architects we can force explicit consideration of service model artifacts in your design process, which helps you to identify the artifacts correctly and at the right level of abstraction to satisfy and align with business needs.

From a modeling perspective, the gap between conventional business and technology models is too large, which is a key contributing factor to the failure of many service-orientation initiatives. We've presented a three-part model with the introduction of a service model in between the business and technology models to promote much closer alignment of your services with the needs of the business. With a detailed service model closely aligned with and derived from the business model, you are well placed to map the service model to a technology model that identifies how each service will be implemented, hosted, and deployed. Capability mapping and the Motion methodology provide an effective way to identify business capabilities and ultimately services. The decomposition of the business into capabilities provides the top-level decoupling for the underlying service contracts, and not the other way around as it usually is today.

Connected systems are instances of the entire three-part model, and they respect the four tenets of service orientation. They can be more completely implemented by using the five pillars of Microsoft's platform technologies. Recall that we asked upfront: How do we avoid making the same mistakes with SOAs that previous, hopeful initiatives have resulted in? How do we ensure that the chosen implementation architecture relates to the actual or desired state of the business? How do we ensure a sustainable solution that can react to the dynamically changing nature of the business? In other words, how can we enable and sustain an agile business? How can we migrate to this new model elegantly and at a pace that we can control? And, how can we make this change with good insight into where we can add the greatest value to the business from the outset?

Service orientation with Web services is only the implementation of a particular model. It is the quality and foundation of the model that determines the answers to these questions.

Acknowledgements

The authors would like to thank Ric Merrifield, director, Microsoft Business Architecture Consulting Group; David Ing, independent software architect; Christian Weyer, architect, thinktecture; Andreas Erlacher, architect, Microsoft Austria; and Sam Chenaur; architect, Microsoft Corporation, for providing feedback on early drafts of this article. We would also like to show our appreciation to Alex Mackman, principal technologist, CM Group Ltd., an excellent researcher and writer who helped us enormously.

About the Authors

Arvindra Sehmi is head of enterprise architecture in the Microsoft EMEA Developer and Platform Evangelism Group. He focuses on enterprise software engineering best-practices adoption throughout the EMEA developer and architect community, and leads architecture evangelism in EMEA for the financial-services industry. Arvindra is editor emeritus of the Microsoft Architecture Journal. He holds a Ph.D. in biomedical engineering and a master's degree in business.

Beat Schwegler is an architect in the Microsoft EMEA Developer and Platform Evangelism Group. He supports and consults to enterprise companies in software architecture and related topics, and is a frequent speaker at international events and conferences. He has more than 13 years of experience in professional software development and architecture, and has been involved in a wide variety of projects, ranging from real-time building control systems and bestselling shrink-wrapped products to large-scale CRM and ERP systems. For the past four years, Beat's main focus has been in the area of service orientation and Web services.

Resources

"Designing Extensible, Versionable XML Formats," Dare Obasanjo (Microsoft Corporation, 2004)

"Modeling and Messaging for Connected Systems," Arvindra Sehmi and Beat Schwegler
A Web cast of a presentation at Enterprise Architect Summit: Barcelona (FTPOline.com, 2005)

MSDN
Guidance Automation Toolkit (GAT)

Obtain a case study on Microsoft Motion methodology by sending a request to motion@microsoft.com.

"Service-Oriented Modeling for Connected Systems: Part 1," Arvindra Sehmi and Beat Schwegler, The Architecture Journal, Issue 7, March 2006.

This article was published in the Architecture Journal, a print and online publication produced by Microsoft. For more articles from this publication, please visit the Architecture Journal website.

© Microsoft Corporation. All rights reserved.