This article shows you how to develop mediation flow components in IBM® WebSphere® Integration Developer for deployment on WebSphere ESB or WebSphere Process Server. It shows you how to build them in an order that minmises development time and rework, and facilitates refactoring, and debugging.
The article is based on extensive experience developing mediation flows. It assumes that you have some experience with WebSphere Integration Developer development and mediation flow development. It doesn't go into detail about terminology or building mediation flows -- it simply outlines some proven steps to make your mediation module development more effective and minimise rework.
Before you start, you need to understand:
- What interfaces will you be working with? Are you designing them, or are they provided?
- What binding types will you be working with? Will you expose your mediation flow as a Web service? Will it consume a JMS- or MQ-based service?
- What will your service do? Do you know how you're going to build it? Which mediation flow primitives are you likely to use?
You may not know all of these details before you start, but the more of them you know, the less likely it is that you'll need to rework your mediation flow later. Reading this article before you develop your next mediation flow should further increase your understanding of the things you need to know before you start work.
Define or discover the interfaces that you'll be working with
The first thing is to do is establish the interfaces you're working with, both on the front end (how the service you're building is exposed) and the back end (how the services you're calling are exposed). Good SOA principles dictate loose coupling and tightly-defined service interfaces, so the rest of your construction should be dictated by these interfaces. They may come from third parties, or you may be defining them yourself, in which case it is a good idea to define a wrapper type object for each chunk of request and response information, to avoid some subtle problems later on. Examples of these wrapper type objects are shown in Figures 1 and 2:
Figure 1. Example interface with wrapper types

Figure 2. Example wrapper type

In general, it will make life easier if you spend time now getting your interfaces right. Although refactoring and change is always possible later, things will go more smoothly if you get strong definitions for the interfaces up front, so that you can minimise later changes to them.
Make sure that you add modeled faults wherever you expect that the interface may need to throw a fault -- it's always easier to work with modeled faults than unmodeled faults. Here is an example of an interface with some modeled faults:
Figure 3. Example interface with modeled faults

Make sure the appropriate business or technical data is added to the modeled faults. (Modeled faults are sometimes called service business exceptions or checked faults. However, there is no reason to restrict them to business-type faults: you should use wherever you expect a fault could be thrown.)
Now, place the interfaces on an assembly diagram so that you can define imports and exports. Here are the ways your mediation module is going to communicate with the outside world:
Figure 4. Creation of imports and exports

If you don't like the generated names for the imports and exports, change them now. The more embedded they become in your environment, the more difficult it will be to change them later.
Now place the mediation flow component itself on the assembly diagram, and connect it to the imports and exports. Don't forget to rename the component. This step enables you to define the interfaces and references on the component, and completes the high-level picture of your module, as shown in the assembly diagram:
Figure 5. High-level assembly diagram

The example above is a simple one with one export and import specified, but if you need more, add them now.
Define implementations for each operation in the mediation flow
Next, continue the top-down development approach by beginning to implement the mediation flow component by creating a new implementation. For each operation on the left-side (that you are exposing), define an implementation (the only exception is if you don't want to implement the entire interface now).
For each operation, you'll need to decide whether to use the callout feature of the mediation flow component to create a complete request and response flow for one of the back-end services, or whether to simply use a chain of Service Invoke primitives to invoke each of your back-end services. This choice is a conceptual and design matter more than a technical one. In general, it's best to drag across to one of the operations on one of the references, and therefore define a single callout, if there is one clear primary reference the mediation flow will invoke. Here's an example:
Figure 6. Single callout definition

This situation can arise, for example, if the back-end service that corresponds to the callout is complex, and the rest of our mediation flow simply augments the message that is ultimately sent to it with data retrieved from other services via the Service Invoke primitive.
If the mediation flow will invoke several references, and none of them is obviously the primary one, then they should be considered peers and it's better to use Service Invoke primitives to invoke all back-end services. Here's an example:
Figure 7. Service invokes for peer back-ends

There is no important technical difference between these approaches, but it makes the distinction clear to someone who later maintains or reads the flow between a service that is invoking one primary back-end and simply using calls out to other services to augment its behaviour, and one that is invoking several peer services to perform its task. The underlying behaviour of the mediation flow engine is very similar in both cases.
Define and specify the context objects you want to use
The next step is to define the mediation flow contexts (correlation, transient, and shared) you want to use. It's important to do this step at this stage, as the definitions get baked in to the XSLT or BO maps that you may define later, so defining them now minmises later rework. A good practice is to define a wrapper BO type for context you expect to use (probably stored in the module itself) that can contain the relevant chunks of data. Doing so is important because each context can contain only one object of one type. Also, the wrapper gives you some potential for adding fields to the context later. Here's an example of what such a wrapper business object looks like:
Figure 8. Wrapper object for correlation context

Consider the transient context to be a bit like a set of local variables in a programming language. Typically, you use it to store temporary data inside a flow that's created by one mediation primitive
and used by another one. For example, when one mediation primitive will overwrite the /body section of the Service Message Object, and there is data in there you need to preserve,
you can save it in the transient context. Therefore, you need to think about the fields you'll need ahead of time.
The correlation context is typically used for data shared between request and response flows in a mediation flow. You might use it, for example, when you require a unique ID for each message that's shared for logging purposes. Again, you need to understand your requirements ahead of time, so that you can define the correlation context wrapper type. The shared context is typically used when you are working with branching logic in a mediation flow. For more information, see the developerWorks article Aggregation functionality in WebSphere ESB V6.1.
Define the message-type flow of the mediation flow
Now it's time to start defining the flow itself by putting in primitives.
Firstly, you'll want to define the basic structure of the flow by adding all the primitives you're expecting to use and writing them together. During this phase, you don't generally set properties on the primitives. It's especially important during this phase to get the message types right: in other words, ensure that all the terminals of the various message primitives have their message types set as you expect them to end up. Defining the form of the flow and the types that will be used throughout will make it easier to come back later and define the properties on those primitives, rather than doing both in parallel. It will also provide some validation that the basic structure of the flow will hang together. Here are some rules to follow:
- Work from left to right: first create the first primitive you intend to use and wire it up to the input node. Then create the second primitive, and wire it up to the first, and so on.
- Whenever you create a primitive that can have a variable number of output terminals, create them as you go, to ensure that all possible paths of flow are apparent.
- Whenever you create a primitive where the output terminal type doesn't have to be the same as the input terminal type (such as the Custom Mediation, the XSLT or the BO Map), define the output terminal type manually as you go, ensuring that the types of the terminals are set.
- Whenever you create a Set Message Type or Type Filter primitive, define the Message Type Refinements table or Filters table as you go to make sure that downstream (logically, to the right) primitives are aware that part of the message is more or less specific than it was upstream. This rule is an exception to the above rule of not setting mediation properties during this phase.
- When you create a Service Invoke primitive in the flow, the tool asks you to specify the partner reference and operation that should be invoked. Specify this correctly, as it will automatically set the terminal types appropriately for you.
- During this phase, change the names of all primitives that you create as you go from the default name to a name that is meaningful to you or that satisfies your naming conventions. Doing so ensures that the names of any artifacts that you create later will be automatically derived from primitive names and match up accurately.
- You don't need to include any non-functional primitives, such as ones that do logging, as long as they don't change the message type. You can insert those later.
Sometimes, it's possible to work from the right instead or simultaneously from both directions. Doing so can be useful in simple flows, particularly when doing mapping: as the Mediation Flow Editor understands what the type of the output node is, it can set the output terminal types automatically on primitives that can have varied output terminal types. Here is an example:
Figure 9. Example of working from the right

The type of the highlighted terminal shouldn't be set manually, but instead just connected to the Partner callout, which causes its type to be set automatically.
Now, define the maps on the XSLT and BO map primitives that you've placed in the flow. Because you've already defined the types of the terminals on all the mediation primitives in the flow, this task should be as straightforward as possible. You simply define a new map, and the input and output types of the map will be set automatically, as shown below:
Figure 10. Definition of XSLT Map, showing automatic type inference

Now it's time to go through and set properties appropriately on all the remaining mediation primitives for which you haven't already defined the properties. Don't miss any!
Define primitives that don't alter message type
As mentioned above, some people use custom mediations for logging or other non-functional purposes. If so (and they don't change the message type), it makes sense to put them in last, perhaps even after an initial round of testing, and it is more straightforward to set the terminal types appropriately. As of Service Registry V6.2, it's easier to do this: simply drop the new primitive on a wire, and it will be inserted in the appropriate place. For primitives with flexible terminal types, such as the Custom Mediation, the output terminal type will still need to be set appropriately.
You've now completed the initial build of the flow you're going to use -- it's time to test! WebSphere Integration Developer has a unit test infrastructure that's ideal for testing the mediation flow you've just built. See the Resources section for more information.
The author would like to thank Kim Clark and Dave George of IBM for their feedback on and help with this article.
- Getting started with WebSphere ESB and WebSphere Integration Developer
This article provides a more general introduction to mediation flow development. Whilst it refers to an older version of WebSphere ESB, is nevertheless still useful and relevant. - Aggregation functionality in WebSphere ESB V6.1
This article describes in more detail WebSphere ESB branching logic and shared context. - SOA Tips 'n' Tricks blog
Latest tips for WebSphere ESB and related products. - WebSphere ESB developer resources page
Technical resources to help you use WebSphere ESB as a flexible connectivity infrastructure for integrating applications and services to support an SOA. - WebSphere ESB product page
Product descriptions, product news, training information, support information, and more. - WebSphere ESB information center
A single Web portal to all WebSphere ESB documentation, with conceptual, task, and reference information on installing, configuring, and using WebSphere ESB. - WebSphere ESB documentation library
WebSphere ESB product manuals. - WebSphere ESB FAQs
Basic questions and answers about the new WebSphere ESB product and its relationship to other WebSphere products. - WebSphere ESB support
A searchable database of support problems and their solutions, plus downloads, fixes, problem tracking, and more. - Redbook: Patterns: SOA Design Using WebSphere Message Broker and WebSphere ESB
Patterns for e-business are a group of proven, reusable assets that can be used to increase the speed of developing and deploying e-business applications. This Redbook shows you how to use WebSphere ESB together with WebSphere Message Broker to implement an ESB within an SOA. Includes scenario to demonstrate design, development, and deployment. - WebSphere Process Server developer resources page
Technical resources to help you use WebSphere Process Server. - WebSphere Process Server product page
Product descriptions, product news, training information, support information, and more. - WebSphere Process Server information center
A single Web portal to all WebSphere Process Server documentation, with conceptual, task, and reference information on installing, configuring, and using WebSphere Process Server. - WebSphere Process Server requirements
Hardware and software requirements for WebSphere Process Server. - WebSphere Process Server support
A searchable database of support problems and their solutions, plus downloads, fixes, problem tracking, and more. - developerWorks WebSphere zone
Technical information and resources for developers who use WebSphere products. developerWorks WebSphere provides product downloads, how-to information, support resources, and a free technical library of more than 2000 technical articles, tutorials, best practices, IBM Redbooks, and online product manuals. Whether you're a beginner, an expert, or somewhere in between, you'll find what you need to build enterprise-scale SOA solutions using the open-standards-based WebSphere software platform. - WebSphere SOA solutions developer resources page
Technical resources for WebSphere SOA solutions. - developerWorks SOA and Web services zone
Technical resources for evaluating, planning, designing, and implementing solutions that involve SOA and Web services. - developerWorks WebSphere application connectivity zone
Access to WebSphere application connectivity (formerly WebSphere business integration) how-to articles, downloads, tutorials, education, product info, and more. - developerWorks WebSphere business process management zone
Access to WebSphere BPM how-to articles, downloads, tutorials, education, product info, and other resources to help you model, assemble, deploy, and manage business processes. - WebSphere business process management products page
For both business and technical users, a handy overview of all business process management products. - WebSphere forums
Product-specific forums where you can get answers to your technical questions and share your expertise with other WebSphere users. - Most popular WebSphere trial downloads
No-charge trial downloads for key WebSphere products. - Trial downloads for IBM software products
No-charge trial downloads for selected IBM® DB2®, Lotus®, Rational®, Tivoli®, and WebSphere® products. - Technical books from IBM Press
Convenient online ordering through Barnes & Noble. - developerWorks technical events and Webcasts
Free technical sessions by IBM experts that can accelerate your learning curve and help you succeed in your most difficult software projects. Sessions range from one-hour Webcasts to half-day and full-day live sessions in cities worldwide.

Andrew Ferrier is a consultant with IBM Software Services, specialising in WebSphere ESB. He regularly works with customers across Europe and beyond to enable them to work effectively with WebSphere ESB and other IBM products. He writes extensively on these topics, particularly at the SOA Tips 'n' Tricks blog, which he co-founded.





