Implementing user contexts across multiple WebSphere ESB mediation flows in IBM Integration Designer
Are you authoring mediation flows in IBM® Integration Designer (hereafter called Integration Designer) to deploy on WebSphere Enterprise Service Bus (ESB) and need to pass extra information between two or more mediation flows? You read the documentation to decide which of the "user-defined contexts" to use in order to accomplish this and you opt to use user contexts as they seem to fit your needs.
Next, you open your flow, look to the right-hand side of your Integration Designer window for the Context palette and you see Correlation, Transient, and Shared contexts, but not User Context. This leads you to the question, how do you actually implement user contexts? Here is a step-by-step guide that includes an example for you to try.
This article assumes that you have prior experience creating mediation flows and deploying them to WebSphere ESB.
To deploy the sample that is provided with this article, you will need:
- IBM WebSphere ESB V7.5.1 or above
- IBM Integration Designer V7.5.1 or above
Overview of contexts
The Service Message Object (SMO) context lets mediation primitives pass data between themselves that is not part of the message payload. SMO context objects are either user-defined or system-defined.
What are system-defined context objects?
The following context objects are system-defined:
- failInfo: Context is used to hold exception information.
- primitiveContext: The object contains information used by specific mediation primitives.
- dynamicProperty: The object is used to override promoted properties.
What are user-defined context objects?
You can use user-defined context objects to store properties that can be accessed by mediation primitives later in the flow. The following context objects are user-defined:
- transient: Enables primitives to pass values to each other in the current flow.
- correlation: Enables primitives to pass values from the request flow to its response flow.
- shared: Shares values between all branches of a flow.
- user: Passes values not part of the message payload between the SCA components.
This article guides you though the steps to implement user contexts.
Implementing user contexts
In this section, we will briefly describe the steps to implement user contexts, and then go into more detail in the example contained in the next section.
Unlike the other user-defined contexts, implementing user contexts is not simply a case of adding a business object to the context palette, located in the right-hand side on the Request, Response, or Error tabs (see Figure 1).
Figure 1. Context palette location
In Figure 2, you can see the Context Palette contains Correlation, Transient, and Shared Context, but not User Context.
Figure 2. Context palette
Instead, user contexts are configured using the XSL Transformation or Business Object Map primitives, which are found under the Transformation folder in the Mediation Primitive palette (Figure 3).
Figure 3. Transformation primitives
Initializing user contexts
The following steps will prepare your flow for user contexts:
- We need to introduce an XSL Transformation or Business Object Map
Primitive before you can store anything in the user context. Expand
the userContext section and create a Local map
against the "entries" section (Figure 4). You need to create a Local
map for each value you wish to pass between the SCA modules.
Figure 4. Creating a user context entry
- In the properties for the Local map, enter
1in Cardinality for the first value,
2for the second value and so on, as shown in Figure 5.
Figure 5. Setting cardinality
- Specify a name and optionally a type for your value by entering the
Local map and using Assign, as shown in Figure 6.
Figure 6. Assigning a User Context name and type
name can be assigned as you wish, such as
type can be anything to describe the type being used in the value field, such as
boolean, or complex types such as
- Create a mapping against the "value". The Cast Assist pop-up appears as
shown in Figure 7. Click on Cast target and map
and then select your data type.
Figure 7. Setting the User Context value
- Now you have a Local map against the data type that you selected, as
shown in Figure 8.
Figure 8. Setting User Context value (continued)
- To set a default value, you can either change the Local map to Assign, or open the Local map and add an Assign to the value.
Storing and reading user context values
In the primitive that sets the user context value, for example a Database Lookup primitive, ensure you have specified the correct types for your value, and then set the Target locations as shown in Listing 1 and Figure 9.
Listing 1. Xpath to your user context value
/context/userContext/entries[name = 'MyUserContextName']/value
Figure 9. Storing database contents into the user context
In the primitive that reads and uses the value stored in the user context, you can use the same XPATH as when you stored the value (see Figure 9).
Example: Extending the Stock Quote scenario
You have a business that provides Stock Quote prices to your paying clients. Two levels of membership are available, Gold Membership for "premium" customers and Silver Membership for "standard" customers.
When a client submits a request for a stock price, the payload of the message contains their user ID and the company symbol. The flow then retrieves the client's details from a database and directs them to either the Gold or Silver service as appropriate.
However, you are now introducing a Platinum service for Gold clients with a high credit rating, or who have been a member for a number of years. The logic that determines if a Gold client can use the Platinum service is contained in a separate flow from the database lookup.
This scenario is based on the standard Stock Quote sample available from the Samples and Tutorials help page within IBM Integration Designer. The scenario has been updated with an extra mediation module to handle the check for Platinum service entitlement.
The following sections detail the updates to the original Stock Quote mediation module, the new Platinum Service Check mediation module, and the instructions to run the sample yourself. The files needed to run this sample are included in the Downloadable resources section of this article.
StockQuote mediation module
Figure 10 shows the updated assembly diagram for the StockQuote mediation module.
Figure 10. Updated StockQuote assembly diagram
The StockQuote assembly diagram has been updated to replace the RealtimeService Web Service Import with the new PlatinumServiceCheck SCA Import, as shown in Figure 11.
Figure 11. Updated StockQuote mediation flow
The StockQuote request mediation flow is similar to the original StockQuote mediation flow, but an extra XSLTransformation primitive named CreateUserContextEntries has been added (Figure 11). The Database Lookup primitive (named Lookup) has also been updated to augment the SMO with extra data from the database CUSTOMERTABLE table. The extra data is the YEARSASCUSTOMER and CREDITRATING database columns, which are stored in the SMO correlation context.
When you open the map used by the CreateUserContextEntries XSLTransformation primitive, you see a map similar to the one shown in Figure 12.
Figure 12. CreateUserContextEntries map
The map contains two move operations to move the correlation context and the message body into the output SMO. The three local map operations create three new user context entries so that the number of years as a customer, the customer credit rating value, and the customer ID value are all passed over to the new mediation module that will be called by the PlatinumServiceCheck import.
The three local maps are all similar in that they set up a name and value pair for each of the three customer data items. The local map for storing the number of years as a customer in the user context is shown in Figure 13.
Figure 13. Number of years as a customer local map
Platinum Service Check mediation module
The Platinum Service Check mediation module has been added into the new solution between the original Stock Quote mediation module and the Realtime service. Figure 14 shows an SCA Export, a mediation module, and then two web service exports. The first makes the final call to the Realtime service, and the second makes a call to the Platinum service where the details of the request are stored.
Figure 14. Platinum Service Check assembly diagram
In Figure 15, the request flow for the Platinum Service Check module starts with a Flow Order primitive to split the flow into two branches. The first branch immediately makes the call out to the Realtime service. The second branch of the flow then goes to the Message Filter primitive named PlatinumCheck.
In the PlatinumCheck primitive, an XPath expression is run against the SMO user context entries to check if the number of years as a customer is greater than or equal to 5, or if the customer's credit rating is greater than or equal to 90.
Figure 15. Platinum Service Check mediation module request flow
The details page of the PlatinumCheck primitive is shown in Figure 16. The full XPath expression being used is shown in Listing 2.
Figure 16. PlatinumCheck details page
Listing 2. Xpath expressions
/context/userContext/entries[name = 'CustomerYears']/value >= '5' or /context/userContext/entries[name = 'CreditRating']/value >= '90'
If the XPath expression does not evaluate to "true" (for example, the customer has been a customer for less than 5 years, or the customer has a credit rating of less than 90), the flow is stopped using a Stop primitive and nothing further happens. If the XPath expression in the PlatinumCheck primitive evaluates to "true", the match1 terminal is fired and the flow continues to the ConvertToPlatinumStoreRequest XSL Transformation primitive, and then the GetCustomerIDFromUserContext Message Element Setter primitive. These two primitives simply set up the message for a one-way request to the Platinum service. In a similar way to the PlatinumCheck Message Filter primitive, the GetCustomerIDFromUserContext primitive uses an XPath expression to retrieve the Customer ID value from the SMO user context shown in Figure 17 and in the Message Element Setter properties dialog shown in Figure 17.
/context/userContext/entries[name = 'CustomerID']/value
Figure 17. GetCustomerIDFromUserContext Message Element Setter property dialog
By inspecting the updated StockQuote mediation module and the new PlatinumServiceCheck module, you see an example of how extra information can be passed between SCA modules using the SMO user context. By adding user context entries in one module and accessing the entries in another module, information is passed between modules without requiring changes (such as additional fields) to the service interfaces.
Running the extended Stock Quote sample
To run the sample, download all the files in the Downloadable resources section in this article, and then follow these instructions:
- Import all the modules and libraries from the StockQuoteWithPlatinumCheck.zip file into IBM Integration Designer. You end up with three mediation modules named StockQuote, PlatinumServiceCheck, and BackendServices; and a library module named Resources.
- Start your WebSphere ESB server.
- Prepare the Customer database (a Derby database) by unzipping the
SQCustomerDB.zip file to a directory on your
computer with no spaces in the directory path. In this article, we use
C:/temp. You end up with a directory called SQCustomerDB, which contains the Derby database files.
- Create a data source in WebSphere ESB for the new database:
- Go to the WebSphere ESB Administration Console (normally at
- Log in (if necessary) and go to Resources > JDBC > Data sources.
- Select the appropriate scope for your new Data Source from the drop down list of scopes. "Cell-level" is fine for this sample. Then click the New button.
- Provide a data source name and JNDI name for the new data source. The data source name is "SQCustomer" and the JNDI name must be "jdbc/sample/CustomerDatabase". Click the Next button.
- Select Create new JDBC provider. Click the Next button.
- For the Database type, select Derby. For the Provider type, select Derby JDBC Provider. For the Implementation type, select XA data source. Click the Next button.
- For the Database name, provide the file path to the unzipped
SQCustomerDB directory, for example,
C:/temp/SQCustomerDB. Click the Next button.
- Leave the security aliases as "'(none)", as there is no security in use for this sample database. Click the Next button.
- Review the summary of your Data source. Click the Finish button.
- Save the WebSphere ESB configuration changes by clicking on the Save link.
- Test the connection to the Customer database by clicking the checkbox next to the new Data source in the data sources table, and then clicking the Test connection button. If you do not see a success message, check the settings of the Data source, and in particular, check that the Database name value is correct for where your Derby database files were unzipped in Step 3.
- Go to the WebSphere ESB Administration Console (normally at
- In IBM Integration Designer, add the three mediation module applications to your server by going to the Servers view, right-clicking on your WebSphere ESB server, and selecting Add and Remove from the menu. In the Add and Remove dialog, select BackendServicesApp, PlatinumServiceCheckApp, and StockQuoteApp. Click the Add button to add them all to the server. Click the Finish button to install and start the applications on the WebSphere ESB server.
- Run the sample by using the Integration Test Client in Integration
- In Integration Designer, right-click on the StockQuote project and choose Test > Test Modules. The Integration Test Client opens.
- In the Detailed Properties section, set the Module to StockQuote, the Component to StockQuoteService, the Interface to StockQuoteService, and the Operation to getQuote.
- In the message section, set the symbol value to
AAA and the customerID value to
1000. See Figure 18 for the Integration
Test Client settings.
Figure 18. Integration Test Client settings
- Click the Continue button in the Events section (the green triangular button) to run the test. Select your WebSphere ESB server in the Deployment Location dialog, supply your server login username and password if requested, and click Finish.
- When the test runs, the Integration Test Client calls the
StockQuoteService export in the StockQuote module with the
supplied message. The PlatinumServiceCheck module is called with
the additional user context data, and calls RealtimeService and
PlatinumService (see Figure 19).
Figure 19. Integration Test Client output
You can now see the output "Platinum storeRequest service called" and the contents of the message in the server logs.
The SQCustomerDB supplied has details for five different customers. When you supply different customerID values in the Integration Test Client and re-run the test, you see different outcomes on the server as shown in Table 1.
Table 1. Expected test results
|Customer ID||Subscription level||Years as a customer||Credit rating||Service called||Platinum service called?|
This article described how to use user contexts in WebSphere ESB and IBM Integration Designer, allowing you to pass extra information between mediation modules without changing your service interfaces.
- WebSphere ESB resources
- IBM Integration Designer resources