This article assumes that you are familiar with IBM® WebSphere® Enterprise Service Bus (hereafter called WebSphere ESB). Some experience with custom mediation primitives and Eclipse plug-ins is helpful but not essential. Mediation primitives, whether prepackaged or created by you, are Eclipse plug-ins. This article tells you in general terms what you need to do, then walks you through a specific sample -- a mediation primitive that dumps the Service Message Object (SMO) or some part of it to the console. When you complete this tutorial, your new DumpSMO primitive will appear on the mediation flow editor palette along with the pre-packaged primitives.
Before building your own mediation primitive, it's worth looking at your reasons for doing so and going through a brief cost-benefit analysis, because designing the primitive and writing the Java™ code will take some time. Here are some possible reasons for building your own mediation primitive:
- Because the pre-packaged mediation primitives don't do everything you want them to do.
- This reason is pretty good, but you can build a custom mediation primitive to satisfy this requirement, so it's not good enough.
- Because you want to reuse of your custom mediation primitive implementation.
- When you write your own primitive, users of it simply have to drag it onto the workspace and perhaps supply a few configuration properties, reusing your code in every instance of the primitive. For a custom mediation primitive, its implementation is specific to the single primitive. It is not in itself reusable. However, if you use custom mediation primitives, you can get close to the level of reuse that you get with a mediation primitive plug-in. If you put the bulk of your implementation in a Java library, and then, in each custom mediation primitive instance, just call that library, that library code is reused. However, this technique still requires a line or two of special code in each custom mediation primitive instance.
- Because you want to define your own properties.
- Properties defined on custom mediation primitives are meta-level properties describing the mediation implementation, and they do not provide for properties used by the mediation implementation itself. If you define your own mediation primitive plug-in, you can define properties that the implementation can use.
- Because you want a set of terminals different from the standard set.
- You cannot add new terminals to a custom mediation primitive. If you need something other than the standard set of one input, one output, and one fail terminal, then you have to define your own mediation primitive plug-in.
- Because user-defined mediation primitives are cool.
- OK, this reason is a bit lame, but some of us get excited seeing our own icon on the mediation flow editor palette.
High-level steps for creating your own mediation primitive plug-in
Each of these high-level steps is covered in a section below.
- Build the plug-in project, which contains the information for the visual aspect of the mediation primitive. It describes what you see in the mediation flow editor.
- Build the Java project, which is the actual implementation of the mediation primitive.
- Deploy the plug-in project, which is an Eclipse plug-in and must be deployed as one.
- Deploy the Java project. The implementation must reside somewhere where the runtime can find it.
- Test the new mediation primitive.
- WebSphere Integration Developer V6.0.2 or later, with either a WebSphere ESB server or WebSphere Process Server as your test server.
- The sample files for this article, which you can download below. The article assumes that you unzip them into C:\.
There is nothing magical about mediation primitives -- they are simply specialized Eclipse plug-ins. Creating them is a bit tedious, but not difficult. To build the plug-in, use the Plug-in Development Environment that comes with WebSphere Integration Developer:
- Open the Plug-in Development Environment perspective:
- Select Window => Open Perspective => Other.
- In the Select Perspective popup window, check Show All, select Plug-in Development, and click OK.
- In the confirmation pop-up window, click OK.
- Select File => New => Plug-in Project.
- In the New Plug-in Project popup window:
- Set the Project Name to com.ibm.wesb.samples.dumpSMO. The Eclipse convention is to give plug-ins Java-package-like names.
- Under Project Settings, uncheck Create a Java project. We want our Java project to be separate from the GUI project.
- Click Next.
- Click Finish.
You should now see the plug-in manifest editor, which lets you configure the plug-in project. Under the covers, you are editing the file plugin.xml.
There are two extensions that have to be configured: the handler extension, which provides the details about the primitive; and the UI contribution extension, which holds the icons for the primitive.
- In the plug-in manifest editor, select the Extensions tab.
- Click Add.
- In the New Extension popup window:
- Near the bottom, uncheck Show only extension points from the required plug-ins. The Mediation Flow editor plug-ins are not required, so you won't see them unless you uncheck this option.
- About 1/3 of the way down the list, select com.ibm.wbit.sib.mediation.primitives.registry.mediationPrimitiveHandlers.
- Click Finish.
- Back in the plug-in manifest editor, right click on com.ibm.wbit.sib.mediation.primitives.registry.mediationPrimitiveHandlers and select New => mediationPrimitiveHandler.
- Make sure that the mediation primitive handler that you just created is selected, and fill in the Extension Element Details on the right with the following values (as shown in the figure):
- typeName: DumpSMO
- typeNamespace: mednode://mednodes/DumpSMO.mednode. This field must begin with mednode://mednodes.
- propertyDefinition: propertygroups/DumpSMOPropertyGroup.xml. You will create this directory and file later.
- implementationClass: com.ibm.wesb.samples.dumpSMO.DumpSMOPlugin. This is the implementation for your mediation primitive plug-in, provided in the download file. You will add it to your workspace later.
- isTerminalTypeDeducible: true. This means that when you define an interface for one of the terminals (wire it to another node's terminal), all of the terminals on your mediation primitive will get the same interface. If you do not specify true then the user would have to explicitly define each terminal's interface.
Mediation primitive handler extension
Let's describe this mediation primitive. There are two descriptions: the short description appears when you hover over the icon on the mediation flow editor palette, and at the top of the properties panel. The long description does not appear in the mediation flow editor, but you should include it for Eclipse plug-in completeness. Start with the short description:
- Right click on (mediationPrimitiveHandler) and select New => shortDescription.
- At the bottom of the editor, open Body Text and type in a short description of the mediation plug-in, such as Dump the SMO.
- At the far right, click Apply.
Provide a long description of the plug-in:
- Right click on (mediationPrimitiveHandler) and select New => longDescription.
- At the bottom of the editor, open Body Text and type in a long description of the mediation plug-in: Dump to the console some or all of the SMO, depending on the XPath that the user specified.
- Click Apply.
Now that you've described the general plug-in details, you have to describe some specifics, such as each terminal. A mediation primitive has three types of terminals: input, output, and fail. You can only have 0 or 1 fail terminals, but you can have 0 or more input and output terminals. Each terminal has a name.
A terminal may be dynamic, meaning that there is no fixed number of that variety. You simply describe a single terminal of that variety and set the isDynamic flag to true. Users of your mediation primitive can then place as many terminals of that type on the primitive as they please. The filter mediation primitive takes advantage of this feature -- with that primitive, you can create as many output terminals as necessary, and define filters for each output. Of course, doing so means that your Java implementation of the primitive must be able to deal with this dynamic nature of your primitive. But that is not hard, as explained below. The DumpSMO example has a fixed set of terminals -- the typical set of one input, one output, and one fail terminal.
Describe the input terminal:
- Right click on (mediationPrimitiveHandler) and select New => terminalCategory.
- Fill in the Extension Element Details on the right with the following values:
- type: input
- name: in
- isDynamic: (leave blank)
Describe the output terminal:
- Right click on (mediationPrimitiveHandler) and select New => terminalCategory.
- Fill in the Extension Element Details on the right with the following values:
- type: output
- name: out
- isDynamic: (leave blank)
Describe the fail terminal:
- Right click on (mediationPrimitiveHandler) and select New => terminalCategory.
- Fill in the Extension Element Details on the right with the following values:
- type: fail
- name: fail (The name of the fail terminal is required to be fail).
- isDynamic: (leave blank)
Your extension should now look like this:
Mediation primitive handler extension
Now let's add the UI contribution extension, which describes the icons for the primitive. You have to be a bit artistic at this stage. You need two icons that should be the same picture, but in different sizes. The large icon (32 x 32 pixels) appears on the mediation flow editor palette, and the small icon (16 x 6 pixels) appears on each primitive in the workspace. The sample includes two icons.
- Beside All Extensions on the left, click Add.
- In the New Extension popup window, select com.ibm.wbit.sib.mediation.primitives.registry.mediationPrimitiveUIContribution. (If that extension is not visible, uncheck the option near the bottom labeled Show only extension points from the required plug-ins.)
- Click Finish.
- Right-click on com.ibm.wbit.sib.mediation.primitives.registry.mediationPrimitiveUIContribution and select New => mediationPrimitiveUIContribution.
- Select the mediation primitive UI contribution that you just created and fill in the Extension Element Details on the right with the following values:
- mediationPrimitiveTypeName: DumpSMO
- mediationPrimitiveTypeNamespace: mednode://mednodes/DumpSMO.mednode. These first two fields must be identical to the corresponding fields in the mediation primitive handler, so that they can be associated with each other.
- paletteCategory: /
- smallIcon: icons/dumpSMO.small.gif
- largeIcon: icons/dumpSMO.large.gif.
You will create the icons directory later, at which time you will also copy the provided gif files to that directory.
Your new extension should look like this:
Mediation primitive UI extension
- Save the contents of the plug-in manifest editor.
You have now configured the plug-in. During this process, you have referred to three folders and their files: icons, propertygroups, and mednodes (or mednode://mednodes/). You will now create and populate those folders.
The icons folder:
- In the Package Explorer view on the left side of WebSphere Integration Developer, right-click on our plug-in project com.ibm.wesb.samples.dumpSMO and select New => Folder.
- For Folder Name, type
iconsand click Finish. - Right-click on the icons folder and select Import.
- In the Import popup window, select File System and click Next.
- For From directory, browse to C:\PrimitivePluginFiles.
- On the right side of the File System panel, select both DumpSMO.small.gif and DumpSMO.large.gif and click Finish.
The propertygroups folder:
- In the Package Explorer on the left side of WebSphere Integration Developer, right-click on our plug-in project com.ibm.wesb.samples.dumpSMO and select New => Folder.
- For Folder Name, type
propertygroupsand click Finish. - Right click on icons and select Import.
- In the Import popup window, select File System and click Next.
- For From directory, browse to C:\PrimitivePluginFiles.
- On the right side of the File System panel, select DumpSMOPropertyGroup.xml and click Finish.
This file describes the properties on a mediation primitive. You can have any number of properties -- this example has only one: the XPath to the portion of the SMO to dump to the console. Here are the contents of the file you just imported:
Listing 1. DumpSMOPropertyGroup.xml
<pg:BasePropertyGroups
name="CacheReaderPropertyGroups"
resourceBundle="ESBMediationExamples"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:pg="http://www.ibm.com/propertygroup/6.0.1">
<propertyGroup
name="DumpSMOPropertyGroup"
xsi:type="pg:BasePropertyGroup" >
<property
name="XPath"
displayName="Dump the DataObject at this XPath"
defaultValue="/body"
required="true"
propertyType="String"
id="com.ibm.propertygroup.ext.ui.XPathProperty"
xsi:type="pg:ConstraintSingleValuedProperty">
<description>
An XPath expression to the DataObject which will be dumped to the console.
</description>
</property>
</propertyGroup>
</pg:BasePropertyGroups> |
This file contains a single property group, named DumpSMOPropertyGroup, which contains a single property named XPath, with a number of fields that are self-explanatory. This property will appear in the properties panel for the DumpSMO mediation primitive.
Each property that you define in this file must have a corresponding getter and setter in the implementation for this mediation primitive. In the sample, the implementation will have getXPath and setXPath methods.
The mednode file is the mediation meta-data file. It is a generated file, and is generated with the following steps:
- From the menu bar, select Run => Run As => Run-time Workbench.
- WebSphere Integration Developer launches a new IDE, which takes a few minutes.
- Once the new IDE launches, select Window => Show view => Other => Mediation Development => Mediation Metadata Generation.
- Click OK.
- The mediation primitive that you created is displayed in the Mediation Metadata Generation view of this new IDE. Check the DumpSMO row.
- Click Generate. The status of your mediation primitive should now be OK. The tool has just generated the meta-data mednode file.
- Close this IDE.
- Back in the main WebSphere Integration Developer window, in the Package Explorer view, right-click on your mediation primitive plug-in project and select Refresh.
You should now see a mednodes folder that contains the file DumpSMO.mednode:
The mednodes folder
Now that you have created and populated the necessary folders, you have to make sure that they are included when the plug-in project is built:
- Go back to the plug-in manifest editor, in which you were editing the plugin.xml file.
- Select the Build tab.
- Ensure that the following items are all checked under Binary Build (as shown in the figure):
- The icons folder
- The mednodes folder
- The plugin.xml file
- The propertygroups folder
The build tab of the plug-in manifest editor
- Save the contents of the plug-in manifest editor.
That's it -- you are done building the plug-in project and you have completed this section. The next section shows you how to build the Java project.
You have created the plug-in GUI project. Now you have to create the implementation for this GUI. The sample code includes the Java implementation project, but it is not fully configured, so you need to do a few steps to make the project usable:
- Import the Java project -- the project interchange file C:\PrimitivePluginFiles\DumpSMO.PI.zip.
- When this project interchange file is loaded, the DumpSMO project will have compile-time errors. This code is an SCA/SDO implementation,
so you need to add a library with the SCA/SDO APIs to the build path:
- Right-click on DumpSMO and select Properties.
- Select the Java build path.
- Go to the Libraries tab:
- Click Add Library.
- Select WebSphere ESB Server V6 and click Next.
- Check Configure WebSphere ESB Server classpath and click Finish, then click OK.
Once the project builds, the errors will be gone.
Now let's take a look at the Java code, which is located in DumpSMO => com.ibm.wesb.samples.dumpSMO => DumpSMOPlugin.java and also shown below:
Listing 2. DumpSMOPlugin.java
package com.ibm.wesb.samples.dumpSMO;
import java.io.ByteArrayOutputStream;
import com.ibm.websphere.bo.BOXMLSerializer;
import com.ibm.websphere.sca.ServiceManager;
import com.ibm.wsspi.sibx.mediation.InputTerminal;
import com.ibm.wsspi.sibx.mediation.MediationBusinessException;
import com.ibm.wsspi.sibx.mediation.MediationConfigurationException;
import com.ibm.wsspi.sibx.mediation.OutputTerminal;
import com.ibm.wsspi.sibx.mediation.esb.ESBMediationPrimitive;
import commonj.sdo.DataObject;
public class DumpSMOPlugin extends ESBMediationPrimitive {
private static final String OUTPUT_TERMINAL_NAME = "out";
private String xPath;
public String getXPath() {
return xPath;
}
public void setXPath(String xPath) {
this.xPath = xPath;
}
public void mediate(InputTerminal inputTerminal, DataObject message)
throws MediationConfigurationException, MediationBusinessException {
try {
BOXMLSerializer serializer =
(BOXMLSerializer) ServiceManager.INSTANCE.locateService(
"com/ibm/websphere/bo/BOXMLSerializer");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.writeDataObject(message.getDataObject(
getXPath()),
"urn:someNamespace",
"dump",
baos);
System.out.println(new String(baos.toByteArray()));
// Get the out terminal from the mediation services
OutputTerminal outTerminal = getMediationServices().getOutputTerminal(
OUTPUT_TERMINAL_NAME);
if (outTerminal != null) {
// Fire the message to the out terminal
outTerminal.fire(message);
}
}
catch (Throwable t) {
System.out.println("Problem calling DumpSMO. Not dumping anything.");
t.printStackTrace();
}
}
} |
The actual implementation of this class is not relevant to this article, though you may find it useful as a basis for a more complete primitive of this nature.
The first thing to notice about DumpSMO is that it extends ESBMediationPrimitive, which it must do to reside on the Mediation Flow editor palette. Next, recall that you defined a property named XPath. For that property, this implementation file must have a getter and a setter: getXPath and setXPath.
The bulk of the mediation primitive plug-in implementation is in the mediate method. The parameters are:
- inputTerminal -- This parameter contains information about the input terminal. It is useful if you have more than one. Since this method is called on every input terminal, this field describes the terminal that caused this method to be invoked. You would use this parameter to determine the interface of the input SMO. In this case you have only one input terminal, so you do not use this parameter.
- message -- This is the SMO. It is typed as a DataObject, which the ServiceMessageObject type extends, but it is really a ServiceMessageObject, so if necessary you can down-cast this type to make use of the SMO APIs.
Lastly, after the real work of the primitive is complete, you have to fire the output terminal, which simply requires you to get the output terminal and fire the message through it.
There is one final thing that you must do on this Java project. Since it is the implementation for a mediation primitive plug-in, the project needs the GUI metadata file for that primitive:
- In the Package Explorer view, right-click on com.ibm.wesb.samples.dumpSMO => mednodes => DumpSMO.mednode and select Copy.
- Right-click on the DumpSMO project and select Paste.
That's it. You are now ready to deploy your two projects.
Deploy the Java implementation project
The code for the implementation itself has to be made available to the runtime. The steps below will install this code as a JAR file to the WebSphere Integration Developer test server runtime. If you also want to run this primitive in a standalone WebSphere ESB (or WebSphere Process Server) runtime, copy this JAR file to that installation's $WAS_HOME\lib\ext directory as well.
- Right-click on the Java project DumpSMO and select Export.
- In the Select panel, select JAR file.
- Click Next.
- In the JAR package specification panel:
- JAR file: $WID_HOME\runtimes\bi_v6\lib\ext\DumpSMO.jar
- Leave the remaining fields with their default values.
- Click Finish.
That's it. You have just deployed the implementation for the plug-in. You must restart your server in order for it to recognize this new JAR file.
The plug-in project must be exported as an Eclipse plug-in, which reside in the $WID_HOME\wstools\eclipse directory.
- Right-click on the mediation primitive plug-in project com.ibm.wesb.samples.dumpSMO and select Export.
- In the Select panel, select Deployable plug-ins and fragments and click Next.
- In the Deployable plug-ins and fragments panel:
- Deploy as: a directory structure
- Directory: browse to $WID_HOME\wstools\eclipse
- Leave the remaining fields with their default values.
- Click Finish.
You have now deployed the plug-in project. The last thing you have to do before you can use your newly created primitive is to enable it in WebSphere Integration Developer. Since it's an Eclipse plug-in, you must restart WebSphere Integration Developer in clean mode, which means it reloads all of its plug-ins. If you have an icon on your desktop, follow these steps:
- Shut down WebSphere Integration Developer and restart it with the -clean option:
- Right-click on the WebSphere Integration Developer desktop icon and select Properties.
- Add -clean to the Target field:
WID -clean
- Click Apply.
- Double-click on the WebSphere Integration Developer icon to start it in clean mode.
- While it is starting, you can use the time to roll back what you just did. Remove -clean from the properties Target field. WID -clean is slower than a normal invocation of WebSphere Integration Developer, so you should only use it when instructed, such as when you create new mediation primitives.
- Click OK.
- Once WebSphere Integration Developer is back up, start your test server. Then move to the next section and test your new DumpSMO mediation primitive.
Test your new mediation primitive
You can construct your own mediation module and place an instance of the new DumpSMO mediation primitive onto the mediation flow and test it. Here is what the mediation flow editor should now look like -- when you open it, you should see your new primitive on the palette (circled on the left below). To configure the primitive, go to its properties -- the XPath property is shown at the bottom below:
DumpSMO
Drop this mediation primitive into your flow at various places with various property values. At each point where the mediation primitive executes, you will see in the console something like what you see in Listing 3 below, in which the primitive is configured to display the default XPath: /body. The operation is named operation1 and the single parameter is named input1:
Listing 3. DumpSMO output
<_:dump
xsi:type="intf:operation1RequestMsg"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:intf="http://junk/intf" xmlns:_="urn:namespace">
<operation1>
<input1>hello</input1>
</operation1>
</_:dump> |
By using the DumpSMO sample, you have now learned how to create your own mediation primitive, and you should have that sample functioning within your workspace.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code | PrimitivePluginFiles.zip | 5 KB | HTTP |
Information about download methods
-
Introduction to the IBM Enterprise Service Bus
The ESB architectural pattern supports virtualization and management of service interactions in an SOA. It enables interactions among service providers and requesters and can be implemented using a variety of middleware technologies and programming models. -
Building an Enterprise Service Bus using WebSphere ESB
This three-part article series shows you how to build an ESB with the WebSphere ESB product, in a similar scenario as the previous series on building an ESB with WebSphere Application Server V6. This series also explains the difference between the two approaches, and shows you how WebSphere ESB offers better functionality and better tooling than what was available before. -
Developing custom mediations for WebSphere ESB
This article introduces the use of custom mediations using the WebSphere Integration Developer V6 environment for WebSphere Enterprise Service Bus V6. The article walks you through the development of three types of custom mediations in a simple scenario. -
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 Enterprise Service Bus (ESB) information center
A single Eclipse-based 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. -
WebSphere ESB article: Developing custom mediations
This article describes more complex uses of the custom mediation primitive. -
WebSphere Integration Developer developer resources page
Technical resources to help you use the WebSphere Integration Developer IDE to render your existing IT assets as service components, encouraging reuse and efficiency as you build SOA-based integration solutions across WebSphere Process Server, WebSphere ESB, and WebSphere Adapters. -
WebSphere Integration Developer product page
Product descriptions, product news, training information, support information, and more. -
WebSphere Integration Developer information center
A single Eclipse-based Web portal to all WebSphere Integration Developer documentation, with conceptual, task, and reference information on installing, configuring, and using your WebSphere Integration Developer environment. -
WebSphere Integration Developer information roadmap
Roadmap of articles and resources to help you with installation, migration, administration, development, troubleshooting, and understanding the underlying technology. -
WebSphere Integration Developer documentation library
WebSphere Integration Developer product manuals. -
WebSphere Integration Developer support
A searchable database of support problems and their solutions, plus downloads, fixes, problem tracking, and more. -
developerWorks Java zone
Access to a wealth of free technical information, downloads, and resources for Java developers. -
developerWorks WebSphere Business Integration zone
For developers, access to WebSphere Business Integration how-to articles, downloads, tutorials, education, product info, and more. -
WebSphere Business Integration products page
For both business and technical users, a handy overview of all WebSphere Business Integration 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.
Russell Butek is one of the developers of the IBM WebSphere Web services engine. He is also an IBM representative on the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC 1.0. Previously, he was a developer of the IBM CORBA ORB and an IBM representative on a number of OMG task forces: the portable interceptor task force (of which he was chair), the core task force, and the interoperability task force. You can contact Russell at butek at us.ibm.com.




