5 Tips When Managing Multiple Service Versions

November 28, 2009

Many teams that build service capabilities have to manage multiple versions – this is a problem for any shared asset really – be it a library, component, or service. Using extensible schema contracts (also referred to as Consumer Driven Contracts) you can design service contracts that allow both provider to evolve and consumer to integrate in a flexible manner. In this post, I want to suggest five additional tips when managing web services:

1. Figure out how many versions your team will support concurrently. Too little will force all your consumers to be on a single version and too many will become a maintenance nightmare for you (the provider). In past implementations, I have maintained upto 3 versions while actively moving all service consumers towards one target version. A related approach is to have multiple flavors for your service capability one that returns data that most consumers want, the second that provides the minimal set of attributes, and a third flavor that returns the full list of data items. This may or may not be possible in your case, but something to consider when designing contracts.

2. Figure out how you are going to support multiple versions as a service provider. You can use xml schema namespaces to indicate versions: http://some-company.com/services/CustomService_ver1_0.xsd, ver1_1.xsd and so on. Consider creating a service adapter that can translate back and forth between a new service implementation and the existing one. This can potentially help you with one server side implementation of the functional logic and still service your current and new consumers. This adapter component can perform necessary data transformations, error code & error message translations, and massage response with data attributes as appropriate.

3. Communicate the change in the service capability and gauge the appetite with existing consumers for their ability to absorb the changes in the same release time frame that you are targeting to drop your new version. If you co-ordinate the release, you can get them to new version when you go live. However, for mission critical applications you will want to support both your current and new version concurrently for a small time period before switching the old one off.

4. When you design forward-compatible schemas, you can test the data-binding against multiple platforms. For example, use WSDL2Java if you are using Apache Axis in Java or wsdl.exe if you are in .NET and generate appropriate web service proxy classes and data binding classes. What i have done is to implement JUnit and NUnit automated test cases that run everytime there is a new WSDL or service contract (XSD) change. This will not only validate the service functional logic, but also the forward-compatibility of existing clients. Make sure your when you generate bindings that you generate with both the new schema/wsdl (your updated version) and the existing schema/wsdl files (the version currently used by production clients).

5.  Establish lightweight service governance – it is critical to plan how many service flavors and versions you will support, when will they get upgraded, deprecated, decommissioned, etc. and communicate those with your consumers. Identify checkpoints in your development process where contracts can be reviewed and service behavior can be discussed openly. The well thought out service orientation strategy is a benefit for both the provider and the consumers in your organization.

What other tips/techniques have you used?

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook

Advertisements

Systematic Reuse Success Factor #9 – Consistent API

November 26, 2009

Have you noticed how some application interfaces are consistently named and exhibit consistent behavior across components and services? This can be a critical success factor for systematic reuse. Reusable components are not isolated islands of functionality. Instead, they are meant to be leveraged in a variety of applications and business processes. Consistent interfaces provide several benefits:

  • They reduce learning curve when a developer tries to understand and evaluate the asset for his/her need.
  • Reduces technical debt – consistent API reduces the need to refactor code and reduces regression testing efforts as well.
  • They increase the likelihood of predictable behavior across applications. This is critical for assets that get reused across business processes with an impact ultimately to end user experience (e.g. what if your customer can update address when opening accounts but won’t be able to do that when updating accounts?).
  • Eases integration and testing efforts. Consistent behavior can simplify testing reusable assets. If an asset behaves consistently whether it is invoked by a web application or a backend process, knowledge about test data and integration behavior is applicable across multiple projects
  • Makes documentation easier to follow: consistent interfaces can facilitate the use of templates for document generation as well where similar files/hyperlinks can be generated.

These aren’t the only benefits – feel free to suggest additional ones.


Prefer Real-time Capabilities Even If Your Consumers Don’t

November 25, 2009

Build near real-time capabilities even if your consumers don’t want them. Your consumer may not want a real-time interface or maybe unable to integrate with one. It is tempting to just go for a batch based solution because, that is what your consumer is asking for. For now at least. However, if you build one off batch file extracts or directly expose your legacy system to make one consumer happy, you will encounter the ill effects of tightly coupled systems.

There are several approaches to achieve long-term reuse goals and address the immediate customer need:

  1. Publish a standard message that you will want to treat as a reuse candidate going forward. A subscriber can drain, accumulate messages, transform them to a customer-specific format, and and append it to a file. A scheduled job or process can transfer this file to your customer.
  2. Create a reusable service capability that provides the data in the target format that you want to maintain/evolve going forward. You can create a batch process that shares the same interface that the real-time service uses.  Note: volume is a critical factor here though – you don’t want to make several atomic calls when it is more efficient to fetch data in bulk. You could have a configurable parameter for fetching multiple records at a time – the real-time service can use a much smaller number when compared to the batch process.
  3. For large data volumes,  consider populating a read-only data store using database replication. File extracts can then be driven off this new database. This has the advantage of reducing load on your operational data stores at the same time facilitating additional consumers who might prefer a SQL interface or a file extract based solution. Downsides: additional moving parts and increased cost for a new data store.

When you build real-time capabilities,  adding consumers doesn’t involve too much effort. Are there additional approaches to pursue?

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook


Software Reuse Quick Tip #24

November 25, 2009

Tip #24 – Identify common behavior and encapsulate it

Looking for common behavior across classes is an effective way to reuse behavior. When you find yourself cutting and pasting code, take a step back and reflect on the common behavior that is being implemented. If the duplication is due to the same behavior realized in different ways, introduce a new interface. If multiple objects have the same functionality and can derive from a parent object, introduce an inheritance hierarchy.

This can be done in an iterative fashion as well – if you failed to recognize an interface initially that is okay. Look for opportunities to refactor existing code to introduce a new interface. For example, you can use the Eclipse IDE’s refactoring feature – extract interface – to create a new interface from an existing class.

Why is this important for systematic reuse? Because, by isolating and realizing common behavior you reduce the need for multiple components and classes to re-implement the same functionality. If two classes need the same piece of data, or if they both connect with the same external system, why would you want to code them separately?

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook


Visualize Service Metrics

November 24, 2009

Business applications often utilize log files and databases to capture metrics about usage and error patterns. However, analysis and pattern detecting becomes challenging with additional data and system complexity.  Tree map visualization of application metrics could greatly aid rapid view of system state, error analysis, trends, and remedial actions.  A tree map visualization can be generated using metrics from a database.  It can generate useful views and present information of use to both business stakeholders and the system support team.

Service View – a treemap of metrics organized by service invoked on your SOA platform. The idea is to provide a comprehensive view of the metrics captured and answer questions such as the following: which services are being invoked in the system? Which services receive the highest volume of invocations? How does the volume of service invocations compare with each other? What proportion of invocations in each service was successful and what proportion ended in generating errors?

Transport View – a treemap of metrics organized by kind of transport used to invoke requests in your SOA platform. This is especially useful for systems support staff who need to quickly assess the system-wide impact of messaging providers and their non-availability. The idea is to provide a transport-level view of the metrics captured and answer questions such as the following: what are the transports used by clients when invoking services in your SOA paltform? Which transport mechanism is being used to process the bulk of requests? How does volume of invocations via a transport compare with one another? Which transport is having a higher proportion of errors? Are the failing invocations using reliable transports or are they using unreliable ones?

Status Code View – a treemap of metrics organized by kind of status codes that service requests returned. This is very useful for both development staff and systems support staff. This view displays a bird’s-eye view of the metrics with respect to return codes and answer questions such as the following: what service codes are being returned to clients? What proportion of codes are success codes and erroneous codes? What is the volume of error codes with respect to each other? In summary, this view provides a sense of how the system is performing as a whole – what matters most is whether the platform can provide good response to clients and this is a succinct visualization that answers that.

Are there additional opportunities for visualizing metrics using data in your services layer?

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook


Systematic Reuse Recipe #1 – Minimize Point to Point Integrations

November 21, 2009

Problem Statement

A consuming application/business process wants to integrate with your reusable asset. However, the consumer doesn’t want to take your standard message – wanting a specific format that will make it easier for them. Why? Could be because of several reasons: lack of time/money/skills or technical limitations (e.g. their system can handle only delimited files and cannot parse XML).

Suggested Approach

The immediate, tactical (and often tempting) solution would be to just format the data per the consumer’s format and integrate in a point-to-point fashion. Don’t settle for this option too quickly! Prefer to publish a standard publication in that is in line with your long-term direction (e.g. offer reusable message publications in XML format indicating changes to critical data entities or state changes in business processes). Create a subscriber that tranforms the standard message to the consumer-specific format.

Rationale

If point to point integrations go ungoverned, you will end up with a rat’s nest of tightly coupled integrations that ultimately hurt business agility.Your long-term intent is to have multiple consumers (web applications, backend systems, business processes, etc.) consume reusable message publications.If several business processes need the same core data or notifications about state changes, why would you want to integrate with them separately? Publications will not only reduce integration effort, they place less strain on your system resources – publish once and subscribe several times. No need to query databases or invoke external systems every time there is a new integration.

Note: The additional transformation logic will require extra logging/error handling but over the long haul is a better option than going for a point-to-point integration approach.

This will enable the asset provider, to integrate new applications faster (no need to custom develop messages and integration code for every new consumer) and reduce the cost of maintenance. Reducing application to application coupling is a key motivation for pursuing this approach as well.

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook


Using a Common Architecture for the Services Product Line

November 20, 2009

I introduced the data services product line in earlier posts here and here. As  a follow up I wanted to set the context for a common architecture for this product line. The idea is to have all products in a services product line need to share the same underlying architecture. The common architecture enables the development of a set of common software components and also facilitates variation management, product configuration, and consistent behavior across all the services.

The architecture typically consists of both domain agnostic technical assets and domain specific assets. The domain agnostic assts includes logging, error handling, auditing, metrics, and legacy service invocation modules. The domain specific assets includes data assets, relationships, domain events, and business process workflow components that get triggered based on rules. The common architecture also provides components to integrate with the workflow engine, initialize business processes, as well as provide approval, routing, and escalation steps for any kind of enterprise data entity.

The architecture needs to be reviewed to ensure that it meets the product line’s non-functional requirements such as availability, scalability, and runtime performance.  For instance, supporting high availability can be tricky when data repositories undergo scheduled maintenance on a periodic basis. Scalability is also a key quality attribute that needs to be addressed by the architecture where the need for connection pools, thread pools, and messaging session pools are extensively utilized. Additionally, the architecture can provide caching capabilities for most accessed data records as well as integrate with a lightweight rules engine for fast and efficient rule execution.

Data visibility is another key capability that the architecture needs to address – it can do so by providing an extension point in the processing lifecycle to integrate visibility logic (e.g. filtering attributes, masking data, or utilizing a third party authentication service to validate the identity of the caller etc.).  Ability to assign priorities to jobs in the processing queue based on SLA needs is another feature that could be provided by the common architecture.

Finally, the architecture needs to support several utility features: manage connectivity to each data source, allocate dedicated processor threads based on message volume, and monitor the health of each integration point outside the data service logic. The common product line architecture can potentially address both domain agnostic & domain specific needs.

In a follow up post, I will provide more detail on each of these capabilities and how they align with an agile software reuse approach.

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook


%d bloggers like this: