Part 1 of this series introduced you to the trade system scenario that is used throughout this series. In Part 2, you built and tested the trade system application. In Part 3, you'll learn how to integrate WebSphere Message Broker (hereafter called Message Broker) into a business event processing solution using the trade system scenario as an example.
What are the benefits of integrating Message Broker with WebSphere Business Events (hereafter called Business Events)? Message Broker provides a smart approach to SOA for business application integration and message transformation. Frequently, however, businesses also require business event processing. For example, although your integrated business applications can freely sending each other messages through Message Broker, your business may also need to detect complex message patterns (for example, one of your applications does not appear to be active for a period of time). WebSphere Business Events (hereafter called Business Events) can detect such patterns, automatically generate a message, and send it to Message Broker so the situation can be corrected.
This article assumes that you are using WebSphere Business Events V6.1. WebSphere Business Events V6.2 or later has introduced two new WebSphere Message Broker nodes -- WBEActionInput and WBEEventOutput -- that greatly simplify the integration of WebSphere Business Events with WebSphere Message Broker. For more information, see the topic Integrating WebSphere Business Events with WebSphere Message Broker in the WebSphere Business Events V6.2.1 information center.
The scenario used in this article is based on a trade system in which a Business Events application processes buy and sell trade events. If a stock is bought and sold by the same customer within an hour, a SellAfterBuy action is generated by the Business Events system. For every three SellAfterBuy actions that a particular customer performs within a day, regardless of which stocks the actions are performed on, a SpeculativeCustomer action is generated. For more information on the scenario, see Part 1.
In this article, we'll use the trade system application you created in Part 2, and enhance it to include integration with Message Broker using Message Broker touchpoints to send events and consume actions.
Figure 1 shows the high-level architecture of the Message Broker and Business events integration scenario described in this article:
Figure 1. Message Broker and Business Events integration architecture
In Figure 1, the integration architecture has five key components, three of which are contained in the WebSphere Message Broker "supercomponent":
- The trading system client is responsible for sending requests to Message Broker and receiving responses from Message Broker. For the purposes of this article, we'll use the rfhutil utility available at IH03: WebSphere Message Broker V6-Message display, test & performance utilities to simulate the client.
- In Message Broker, the event/action transformation is responsible for mediating messages throughout the system. This component is the focus of this article. Message Broker receives messages from the client and forwards them to Business Events. It also receives action messages from Business Events and forwards them to the client.
- Business Events detects when a business event has occurred.
- In Message Broker, the trading system processes the trade sent by the client. The Message Broker trading system component is a logical component of a trading processing system and is presented here for completeness. How it is implemented depends on the actual business environment. Because this article focuses on how to integrate Message Broker and Business Events, that is, how to connect the event/action transformation to Business Events, the details of the trading system component not discussed in this article.
- The Message Broker action processing system performs the business process when an action has been initiated by Business Events. Because this article is not focused on business processing capabilities, actions received from Business Events are simply examined and passed to relevant WebSphere MQ queues according to the types of the actions received.
Our integration scenario follows these principles:
- All communication with Business Events is performed using Java Message Service (JMS) message queuing, which is a simple way for Message Broker to connect with Business Events.
- All events submitted to Business Events are processed by a message flow in Message Broker. This enables the transformation of the specific broker messages into the generic event structure required by Business Events.
- Similarly any actions generated by Business Events logically flow through a Message Broker flow, where transformation from the generic action structure to the specific broker messages that may be required by the action processing system can take place. However, the flow described in this article doesn't implement this type of transformation logic.
These principles ensure that neither the Message Broker supercomponent or the client do not require any specific knowledge of the Business Event component other than how to interact with its standard interface, so any possible alterations to the implementation of the Business Event component will not affect the WebSphere Message Broker supercomponent.
You can use the procedure described in this article to build your own projects from scratch. The Message Broker project interchange file and Business Events project file for the solution are included for download. You can import these into the Message Broker Toolkit and Business Events respectively. However, you'll still need to do the manual configuration described in Configure WebSphere MQ.
We'll use WebSphere MQ as the JMS provider for messaging between Message Broker and Business Events, and for messaging between Message Broker and the trading system client. In the following sections, you'll configure the WebSphere MQ JMS and create the necessary queue manager and queues.
JMS queuing is used to pass messages between Message Broker and Business Events. To configure WebSphere MQ JMS, do the following:
- Edit the
INITIAL_CONTEXT_FACTORYandPROVIDER_URLentries in the WebSphere MQ JMSAdmin.config file, in the Java\bin directory of your WebSphere MQ installation. Update these entries as shown below:INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactor PROVIDER_URL=file:/C:/JNDI-Directory.
- Create a separate WebSphere MQ queue connection factory definition
file in a location of your choice, containing the following code
(assuming the queue manager name is WBRK61_DEFAULT_QUEUE_MANAGER):
# Define a QueueConnectionFactory # Only parameters being overridden from their default values are specified. # This sets up a MQ client binding. DEF QCF(qcf1) + TRANSPORT(CLIENT) + QMANAGER(WBRK61_DEFAULT_QUEUE_MANAGER) + HOSTNAME(127.0.0.1)+ PORT(2414) # DEF Q(wbe_input_queue) + QUEUE(WBE_INPUT_QUEUE) + QMANAGER(WBRK61_DEFAULT_QUEUE_MANAGER) # DEF Q(wbe_output_queue) + QUEUE(WBE_OUTPUT_QUEUE) + QMANAGER(WBRK61_DEFAULT_QUEUE_MANAGER) # DEF Q(wbe_backout_queue) + QUEUE(WBE_BACKOUT_QUEUE) + QMANAGER(WBRK61_DEFAULT_QUEUE_MANAGER) END
This file declares that the queue connection factory name is
qcf1, and specifies three JMS queues:wbe_input_queue,wbe_output_queue, andwbe_backout_queue. The corresponding WebSphere MQ queues areWBE_INPUT_QUEUE,WBE_OUTPUT_QUEUE, andWBE_BACKOUT_QUEUE, respectively. Thewbe_backout_queueis needed by the JMSInput node in the Message Broker output flow, which we'll describe about later, for messages backed out by the flow when they can not be successfully processed. - Create a file directory called C:/JNDI-Directory.
- Run the WebSphere MQ
jmsadmincommand with the queue connection factory definition file you created by entering:jmsadmin < your_definition_file
This creates a .bindings file in the C:/JNDI-Directory directory.
Create WebSphere MQ queue manager and queues
Use the WebSphere MQ Explorer to create a a WebSphere MQ queue manager. You
can skip this step if you want to use any existing MQ queue manager, such
as WBRK61_DEFAULT_QUEUE_MANAGER, which may have
been created for you when you installed Message Broker. Otherwise, start
WebSphere MQ Explorer and right-click Queue Managers, then click
New => Queue Manager to create a new queue manager.
If you're using WBRK61_DEFAULT_QUEUE_MANAGER,
you should see the queues shown in Figure 2.
Figure 2. WBRK61_DEFAULT_QUEUE_MANAGER queues
If you are creating, a new queue manager, you'll need to create the following queues yourself:
-
WBE_INPUT_QUEUE -
WBE_OUTPUT_QUEUE -
WBE_BACKOUT_QUEUE -
wmb_input_queue -
wmb_unknown_message_type_queue -
wmb_buy_ack_queue -
wmb_sell_after_buy_queue -
wmb_speculative_customer_queue -
wmb_unknowns_queue
For example, to create WBE_INPUT_QUEUE,
right-click Queues under
WBRK61_DEFAULT_QUEUE_MANAGER and select New
=> Local Queue.
Develop the Message Broker flows
Business Events requires that input event and outbound action objects conform to a general XML format, as described here:
- A
connectoris the top-level XML element that provides information such as the name of the connector and the timestamp of the submission. The connector element can include one connector-bundle child element. - A
connector-bundlecorresponds to either an action or event. Currently a connector message can contain only one event or action. However, an event or action can contain one or more event or action objects; these objects are represented asconnector-objectsin the model. - A
connector-objectmaps to either an event or action object. It includes the name of the object and an array of fields. - The
fieldsare a series of key value pairs in aconnector-object.
The Message Broker flows you develop need to interact with Business Events using the message format shown in the following event message example:
<connector name="Trade System" version="2.2"> <connector-bundle name="Buy" type="event"> <connector-object name="TradeObject"> <field name="CustomerID" type="String"> String_CustomerID </field> <field name="StockID" type="String"> StockA </field> <field name="Date" type="DateTime"> 2008-04-10T14:01:55Z </field> <field name="Quantity" type="Real"> 9.9 </field> <field name="Price" type="Real"> 9.9 </field> </connector-object> </connector-bundle> </connector> |
Figure 3 illustrates the input flow, which uses an MQInput node to read MQ messages from an MQ queue. The input messages are passed to the TradeFilter node to check whether the input messages are of certain types which indicates whether they should be passed to Business Events as events. If so, the messages are passed to the CreateEvent node, which transforms them into a format that Business Events can accept. The MQJMSTransform node then transforms the transformed messages from MQ messages into JMS messages, which can be read by Business Events. The JMSOutput node then sends the JMS messages (now Business Events events) to Business Events. For simplicity, irrelevant messages are sent to the UnknownMessageTypeNode node, which stores them in a MQ queue.
Figure 3. Message Broker input flow
Complete the following steps to create the message flow shown in Figure 3:
- In the Message Broker Toolkit Broker Application Development view, as
shown in Figure 4, create a message flow project by selecting File
=> New => Message Flow Project, and give it a
name of your choice.
Figure 4. Message Broker Toolkit Application Development view
- Create a new message flow by right-clicking on the new project and
selecting
New => Message
Flow.
Name the flow
input. - Drag and drop an MQInput node from the WebSphere MQ drawer in the Palette onto the development canvas.
- Click the node and specify
infor the Queue name property for the node in Properties tab's Basic folder. Assign a value ofXMLNSto the Message domain property in the Input Message Parsing folder.The body of the input messages is expected to have a root element
<Trade>containing five child elements:<Type>,<CustomerID>,<StockID>,<Quantity>, and<Price>. The following is an example of such an input message:<Trade> <Type>Buy</Type> <CustomerID>String_CustomerID</CustomerID> <StockID>StockA</StockID> <Quantity>9.9</Quantity> <Price>9.9</Price> </Trade>
The valid values for the
<Type>element areBuyandSell. We will createBuyandSellmessages at a later stage. - Drag and drop a Filter node from the Routing drawer onto the canvas
and rename it
TradeFilter. The TradeFilter node routes messages ofBuyorSelltypes to itsTrueterminal and all other messages to itsFalseterminal. - Double-click the TradeFilter node and define the
Function Main()as follows:CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN DECLARE myref REFERENCE TO Body.Trade.Type; RETURN (myref='Buy') OR (myref='Sell'); END;
- Drag and drop a Compute node from the Transformation drawer
into the canvas and rename it to
CreateEvent. The CreateEvent node converts the valid input messages to the event message format required by Business Events using the ESQL language. - Double-click the CreateEvent node and define its Main ESQL
function as follows:
CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN CALL CopyMessageHeaders(); -- create <connector name="Trade System" version="2.2"> SET OutputRoot.XML.connector.(XML.Attribute)name = 'Trade System'; SET OutputRoot.XML.connector.(XML.Attribute)version = '2.2'; -- create <connector-bundle name="Buy" type="event"> SET OutputRoot.XML.connector."connector-bundle".(XML.Attribute)name = CAST (InputRoot.XML.Trade.Type AS CHARACTER); SET OutputRoot.XML.connector."connector-bundle".(XML.Attribute)type = 'event'; -- create <connector-object name="TradeObject"> SET OutputRoot.XML.connector."connector-bundle"."connector-object". (XML.Attribute)name = 'TradeObject'; -- create "CustomerID" field SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[1] = InputRoot.XML.Trade.CustomerID; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[1].(XML.Attribute)name = 'CustomerID'; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[1].(XML.Attribute)type = 'String'; -- create "StockID" field SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[2] = InputRoot.XML.Trade.StockID; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[2].(XML.Attribute)name = 'StockID'; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[2].(XML.Attribute)type = 'String'; -- create "Date" field SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[3] = CAST (CURRENT_DATE AS CHARACTER FORMAT 'IU'); SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[3].(XML.Attribute)name = 'Date'; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[3].(XML.Attribute)type = 'DateTime'; -- create "Quantity" field SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[4] = InputRoot.XML.Trade.Quantity; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[4].(XML.Attribute)name = 'Quantity'; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[4].(XML.Attribute)type = 'Real'; -- create "Price" field SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[5] = InputRoot.XML.Trade.Price; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[5].(XML.Attribute)name = 'Price'; SET OutputRoot.XML.connector."connector-bundle"."connector-object". field[5].(XML.Attribute)type = 'Real'; RETURN TRUE; END;
- Drag and drap an MQJMSTransform node from the JMS drawer onto the canvas.
- Drag and drop a MQOutput node from the WebSphere MQ drawer onto the
canvas and rename it to
UnknownMessageTypeQ. Click the node and specifywmb_unknown_message_type_queuefor the Queue name property for the node. - Drag and drop a JMSOutput node from the JMS drawer onto the
canvas. Assign the following values to the associated properties of
the node:
- In the Basic folder, Destination queue =
wbe_input_queue - In the JMS Connection folder, JMS provider name =
WebSphere MQ - In the JMS Connection folder, Initial context factory =
com.sun.jndi.fscontext.RefFSContextFactory - In the JMS Connection folder, Location JNDI bindings:
file:/C:\JNDI-Directory. - In the JMS Connection folder, Connection factory name =
qcf1.
- In the Basic folder, Destination queue =
- Connect all the nodes you just created as shown in Figure 3.
Figure 5 shows the Message Broker output flow. The JMSInput node reads actions generated by Business Events. The JMSMQTransform node transform the messages into MQ messages. The RouteReply node then routes the transformed messages to one of the appropriate MQOutput nodes.
Figure 5. Message Broker output flow
Complete the following steps to create the output message flow shown in Figure 5:
- Create a new message flow and name it
output. - Drag and drop a JMSInput node from the JMS drawer onto the canvas.
Assign the following values to corresponding properties of the node:
- In the Basic folder, Destination queue =
wbe_output_queue - In the JMS Connection folder, JMS provider name =
Websphere MQ - In the JMS Connection folder, Initial context factory =
com.sun.jndi.fscontext.RefFSContextFactory - In the JMS Connection folder, Location JNDI bindings =
file:/C:\JNDI-Directory - In the JMS Connection folder, Connection factory name =
qcf1
- In the Basic folder, Destination queue =
- Drag and drop a Route node from the Routing drawer onto the canvas and
rename it
RouteReply. Right-click RouteReply and select Add Output Terminal twice to create two more output terminals for the node. Name the two new terminalsBuyAckandSellAfterBuyand rename the existing Match terminalSpeculativeCustomer. - Click the RouteReply node and configure the
Filter tableproperty as shown in Figure 6.
Figure 6. Settings for the RouteReply node
This configuration causes theBuy Ack,SellAfterBuyandSpeculativeCustomeractions to be routed to theBuyAck,SellAfterBuy, andSpeculativeCustomeroutput terminals, respectively, and all other messages to be routed to theDefaultterminal. - Create four MQOutput nodes and name them
UnknownsNode,BuyAckNode,SellAfterBuyNode, andSpeculativeCustomerNode. - Set the Queue name properties for these four nodes to
wmb_unknowns_queue,wmb_buy_ack_queue,wmb_sell_after_buy_queue, andwmb_speculative_customer_queuerespectively. - Connect all the nodes you just created together as shown in Figure 3. The Default, BuyAck, SellAfterBuy, and SpeculativeCustomer output terminals are connected to the UnknownsNode, BuyAckNode, SellAfterBuyNode, and SpeculativeCustomerNode nodes, respectively.
Specify message queue connection connector parameters
Even though we're using the Business Events application created in Part 2, because the Business Events message queue connection connector is used to connect to Message Broker, you need to modify the connector parameters of the events and actions of the application. To do this, complete the following steps:
- Start the Design Data tool by selecting Start => All Programs => IBM WebSphere Business Events v6.1 => Design Data.
- Select File => Open Project and then specify the project file name.
- Expand the Touchpoints pane, as shown in Figure 7:
Figure 7. Touchpoints pane
- For each of the Buy and Sell events shown in the Trade System
touchpoint, do the following:
- Right-click on the event and select Event Properties.
- On the Connection tab, select Message Queue Event Connection, and click Configure. Note: You may need to check out the Events first before you can edit them.
- Select JMSQueue as the Queue Type and specify
wbe_input_queueas theQueue Name. - Click Provider and do the following, as shown in Figure
8:
- Select com.sun.jndi.fscontext.RefFSContextFactory for Context Factory Class
- Select file:///C:/JNDI-Directory for URL.
- Select qcf1 for Factory Name.
- Click OK.
Figure 8. Configure JMS queue parameters for events
- Click OK to save the connector configurations.
Complete the following steps to configure connections for the
Buy, Ack,
Sell After Buy, and
Speculative Customer actions in the Trade
System touchpoint:
- Right-click the actions and select Action Properties.
- On the Connection tab, select Message Queue Event Connection and click Configure. You may need to check out the Actions before you can edit them.
- Select JMSQueue as the Queue Type and specify
wbe_output_queueas the Queue Name. - Click Provider and do the following, as shown in Figure 9:
- Select com.sun.jndi.fscontext.RefFSContextFactory for Context Factory Class.
- Select file:///C:/JNDI-Directory for URL.
- Select qcf1 for Factory Name.
- Click OK.
Figure 9. Configure JMS queue parameters for actions
- Click OK to save connector configurations.
Install and test the integration
Now you need to test the Message Broker flows you've created. To test the flows, do the following:
- Follow the instructions in Part 2 to deploy and start your Business Events project.
- Start WebSphere MQ.
- If you haven't already done so, create a Message Broker broker using
the following command:
mqsicreatebroker <brokerName> -i <userName> -a <password> -q <QManagerName> -n <DBName>
- If you haven't already done so, create a Message Broker configuration
manager using the following command:
mqsicreateconfigmgr <configManagerName> -i <userName> -a <password> -q <QueueManagerName>
- Start your broker and configration manager using the following
commands:
mqsistart <brokerName>andmqsistart <configManagerName>. - In the Message Broker Toolkit, create a new Message Broker BAR file by right-clicking the new message flow project you created earlier, and selecting New => Message Broker Archive. Specify a name of your choice for the BAR file.
- In the Prepare pane, select the two new input and output
message flows and click
Build broker archive, as shown in Figure 10.
Figure 10. Prepare the Broker BAR file
- Switch to the Message Broker Toolkit Broker Administration view and create a domain connection to your configuration manager by selecting File => New => Domain Connection.
- Fill in the Queue Manager Name and Port parameters for your configuration manager.
- After your configuration manager is connected, click Next then
the
Finish. - Deploy the BAR file you just created by dragging and dropping it to
the default execution group of your broker, as shown in Figure
11.
Figure 11. Deploy the BAR file
- Use a text editor to create a text file that represents a Buy message
and store it in c:\temp. For example:
<Trade> <Type>Buy</Type> <CustomerID>String_CustomerID</CustomerID> <StockID>StockA</StockID> <Quantity>9.9</Quantity> <Price>9.9</Price> </Trade>
- Create another text file that represents a Sell message and store it
in c:\temp. For example:
<Trade> <Type>Sell</Type> <CustomerID>String_CustomerID</CustomerID> <StockID>StockA</StockID> <Quantity>9.9</Quantity> <Price>9.9</Price> </Trade>
- Use the
rfhutil utility to send the Buy or Sell messages to the
wmb_input_queueon the queue manager you are using (such as, WBRK61_DEFAULT_QUEUE_MANAGER). This can be achieved by click the Read File button to read the Buy message you have just created from c:\temp directory. You can view the content of the buy message by clicking the Data tab on the rfhutil utility, as shown in Figure 12.
Figure 12. View content of a buy message
Then click Write Q to send the message to the wmb_input_queue, as shown in Figure 13.
Figure 13. Send a buy message by clicking the Write Q button
You should see action messages generated by the Business Events flow appear in one of the queues (wmb_buy_ack_queue,wmb_sell_after_buy_queue, andwmb_speculative_customer_queue), depending on the type of the actions. - You can then use the
rfhutil utility
to read the queues. For example, click Read Q to read the
messages in
wmb_buy_ack_queue, as shown in Figure 14:
Figure 14. Click Read Q to read an action message
- Select the Data tab to see the content of the message, as shown
in Figure 15:
Figure 15. Content of a Buy Ack action
- If you send a Sell message immediately after a Buy message, you
should see a message in
wmb_sell_after_buy_queue, indicating that a Sell After Buy event has occurred. - If you repeat the Buy followed by sell messaging cycle three times,
you should see an action message stored in the
wmb_speculative_customer_queuequeue
Alternative integration methods
For simplicity, the solution described in this article uses the Business Events built-in message queue connection connector to connect Message Broker and Business Events. This means that the Message Broker JMS messages are placed in and read from JMS queues mediating Message Broker and Business Events. In terms of performance, this is not the best solution because the message queue connection connector in the middle incurs extra messaging costs. This is because event messages are forwarded to the Business Events engine by the message queue connection connector rather than directly sent to the engine.
One quick solution is to configure the JMSOutput node in the Message Broker
input flow to send events directly to the Message Broker
jms/eventTopic or the
jms/durableEventTopic topics, and configure the
JMSInput node in the Message Broker output flow
to receive JMS messages directed from the
jms/actionTopic or the
jms/durableActionTopic. However, such a
configuration does not currently support the Business Events
ResultEvent and will, therefore, send all
actions to your JMSInput node. You can also use
other connection support, such as HTTP/SOAP/File, to connect to other
Business Events built-in connectors.
In this article you learned how you can quickly configure Message Broker and Business Events for interoperability. We used example Broker messages to describe how event messages for Business Events can be constructed and sent to Business Events by a Broker message flow, and how action messages from Business Events can be received and processed by a Broker message flow.
| Description | Name | Size | Download method |
|---|---|---|---|
| Completed WebSphere Message Broker project file | BrokerProject.zip | 4KB | HTTP |
| Completed WebSphere Business Events project file | WBEBrokerProject.zip | 3KB | HTTP |
Information about download methods
-
Business
event processing with WebSphere Business Events, Part 1: An introduction
(developerWorks 2008): Part 1 of this series introduces you to key
WebSphere Business Events concepts and tools.
-
Business
event processing with WebSphere Business Events, Part 2: Building a business events
application
(developerWorks 2008): Part 2 of this series describes how to build and
test a simple Business Events application.
-
WebSphere Business Events:
Get product information, including features, benefits, demos and trial downloads.
- WebSphere Business Events V6.1 Information Center:
Get complete product documentation.
- WebSphere Business Events V6.2.1 Information Center:
Get complete product documentation.
-
WebSphere Business
Events V6.1 forum:
Share your experiences and questions with other WebSphere Business Events
users.
-
Business
Event Processing from IBM: A Smart SOA Solution:
Get more information on IBM business event processing products.
-
developerWorks
Message Broker zone:
Get the latest techical resources for WebSphere Message Broker, including
downloads, demos, articles, tutorials, events, webcasts, and more.
-
developerWorks BPM zone:
Get the latest technical resources on IBM BPM solutions, including
downloads, demos, articles, tutorials, events, webcasts, and more.
-
Business Process Management enabled by SOA:
Get product information, including features and benefits.

Xiaoming Zhang is a Software Engineer at the IBM Hursley Software Lab. He has done testing, development, and Level 3 service for WebSphere MQ, WebSphere Message Broker, and WebSphere Business Events. Before joining IBM in 1998, Xiaoming was a lecturer in Computer Science at Brunel University in the UK. Xiaoming graduated from Fudan University in China, and received a Ph.D from the University of Wales Swansea, UK. You can reach Xiaoming at zhang@uk.ibm.com.
Comments (Undergoing maintenance)





