In the previous tutorial Working With Simple Data Types from a Process in WebSphere Integration Developer 6 we learned how to work with simple input and ouput data types from a process. In real life, you may have to work with more complex data types such as Order, Address and Customer. In this tutorial, we will learn how to define complex data types and use them from a process. We will also learn how to define your own service interface and implement it from a process.
This tutorial builds on the previous tutorial WASKB020 – Working With Simple Data Types from a Process in WebSphere Integration Developer 6. You must complete that tutorial first.
The Business Logic
In this tutorial, we will build a price quote and availability process. The caller of the process will pass a price quote request object that has the following fields.
- BusinessID – The unique identifier of the business requesting the price quote. Type: xsd:string.
- ProductSKU – The Stock Keeping Unit number that uniquely identifies the product. Type: xsd:string.
- Quantity – The amount of the product required. Type: xsd:double.
The process prepares a quote response message that has these fields.
- QuoteID – An identifier for the quote. If an order is placed by the caller at a later time the quote number will be used to refer to the quote. Type: xsd:string.
- StatusCode – Indicates the nature of the quote response. For example, “ITEM_AVAILABLE” indicates that sufficient quantity of the product is available in the inventory. “ITEM_UNAVAILABLE” indicates otherwise. “ITEM_UNKNOWN” indicates an invalid product SKU. Type: xsd:string.
- ProductSKU – The product identifier. Type: xsd:string.
- UnitPrice – The unit price for the product. Type: xsd:double.
- Currency. Type: xsd:string.
Define the Data Types
In WID, custom data types are called Business Objects. They are defined as XML elements in schema files. The tool simplifies developing the XML schema. You don’t really have to know much about XML schema to complete this tutorial or get useful work done out of WID. At the same time, it is recommended that you learn XML schema before getting into more advanced SOA based application development.
Launch WID if it is not already running. Start the WebSphere Process Server.
The Business Integration module – SimpleModule – should have been already created from the previous tutorials. Expand it. Right click on Data Types and select New->Business Object.
Enter the following values.
Namespace: Accept the default. For more serious programming, there will be a corporate standard for the namespace. Namespace is important. Keep in mind that the fully qualified name of the data type is actually a combination of the namespace and the type name. Folder: types. It is a good idea to define your types in a sub folder rather than directly in the root folder of the module.
Name: QuoteRequest. This is the type name.
Click on Finish.
System opens the data type in the business object editor. Wait for the workspace to be re-built and re-published. This can take up to a minute.
Activate the Properties view. Select the QuoteRequest type in the editor. You should see various properties of the type in the Properties view.
Now, we will add various attributes to the business object. Right click on the QuoteRequest business object and select Add Attribute. With the newly added attribute selected, go to the Properties view. Make sure that the Description tab is selected. Enter the following values.
Add two more attributes as follows.
At this point the business object will look like this.
Save changes (Control+S). System will build the workspace and publish the project. Wait for this to be over.
Create another business object called QuoteResponse. Add the following attributes.
Save Changes. Wait for publishing to complete.
Refine the Data Type
The StatusCode attribute of the QuoteResponse object should contain a limited set of values. We can enforce that by refining the data type a little more. In the business object editor, select the StatusCode attribute. In the Properties view, select the Only permit certain values check box. Select the Enumeration radio button. Add the following values.
Save changes. Close all business object editors.
Define an Interface
In the previous tutorials, we chose to have the interface generated by the system. In this step, we will define an interface that the price quote business process will later implement.
In the Business Integration view, right click on Interfaces and select New->Interface. Enter the following values.
Namespace: Accept the default.
Click on Finish. System will open the interface in the editor. An interface is nothing other than an abstract service description in a WSDL file. If you know WSDL syntax, an abstract service is defined using the <portType> element. The interface editor is quite easy to use and you don’t need to know much about WSDL file syntax.
Our process will accept a QuoteRequest object and reply a QuoteResponse object. As a result, we need to add a request-response type operation to the interface.
In the interface editor, click on the Add Request Response Operation toolbar button. Set the name of the operation to getPriceAvailabilityQuote.
Right click on the getPriceAvailabilityQuote operation and select Add Input. Change the name of the input to request. By default, the data type of the input is string. Click on string and select QuoteRequest.
Right click on the getPriceAvailabilityQuote operation again and select Add Output. Set the name of the output to response. Change the data type to QuoteResponse.
Save changes. System will create the interface in the IQuoteRequest.wsdl file within the interfaces folder. The interface definition is now complete.
Create the Process
In this step we will create a price quote request process that implements the IQuoteRequest interface.
Expand SimpleModule->Business Logic->Processes. Right click on Processes and select New->Business Process. Next to the Folder text box, use the Browse button to select the procs folder that was created in a previous tutorial. Enter PriceAvailabilityQuote as the name of the process. Click on Next. Choose Select and existing interface. Click on the Browse button and select the IPriceAvailabilityQuote interface. Click on OK. There is only one operation in that interface (getPriceAvailavilityQuote) and system should select it by default.
Click on Finish.
Investigate the Generated Process
A newly created process has useful amount of work already done. For example, note the following.
- A variable called Request of type QuoteRequest is already added. This variable is also configured with the Receive activity to store the input data.
- A variable called Response of type QuoteResponse is already added. This variable is also configured with the Reply activity so that the reply data is obtained from this variable.
This, obviously saves us a lot of time.
Work With the Input Data
We will first learn to work with the input data. When a process begins to execute, system automatically creates a new object to store the input data and initializes the process variable associated with the receive activity. In other words, we don’t have to do anything to initialize our Request variable. System takes care of this.
Add a snippet activity below the receive activity. Change the name of the snippet activity to PrintRequest. Set the Java code for the snippet to as follows.
System.out.println("Received a quote request"); System.out.println("Business ID: " + Request.getString("BusinessID")); System.out.println("Product: " + Request.getString("ProductSKU")); System.out.println("Quantity: " + Request.getDouble("Quantity"));
Save changes. What went on here? Every process variable is actually a Java object of class commonj.sdo.DataObject. The class provides a simple getter methods (such as getString and getDouble) to retrieve the fields of the business object. You just have to be careful so that the attribute names are spelled correctly.
Add the Process to Assembly
We must add the process to the module assembly before we can test it. Double click on SimpleModule->SimpleModule to open the assembly editor. Drag and drop the PriceAvailabilityQuote process into the assembly editor. Save changes.
Test the Process
|Defect with publishing WID v6 exhibits buggy behavior when it comes to building and publishing of a Business Integration module. The number of defects is somewhat less if you have installed the Fix Pak 22.214.171.124. It is quite common to get the following exception during the publish process. com.ibm.websphere.management.exception.AdminException: Configuration.MissingValidFrom If you get an error message after a build, make sure that there are no compilation error. If the publishing process fails, take these steps: 1. Double click on the server in the Servers view. Uncheck the Enable automatic publishing checkbox. Save and close the settings. This needs to be done only once. 2. Every time you have a problem with publishing, stop the server. 3. Clean all generated artifacts by selecting Project->Clean from the menubar. System will automatically rebuild the projects. 4. Start the server. 5. Manually publish the module by right clicking on the server in the Servers view and selecting Publish. Since, automatic publish is disabled, you will need to manually publish the project every time you make any changes.|
If the system is publishing the project, wait for it to complete. In the Servers view, right click on the server and select Restart Project->SimpleModuleApp.
In the assembly editor, click anywhere and select Test Module. In the automated test client, choose these values.
Enter some values for the request fields as shown above. Then click on Continue. Make sure that the Console view shows the correct output.
Close the test client. Don’t save changes.
Work With Output Data
It is somewhat more difficult to work with the output data. This is because, system does not automatically instantiate an object and initialize the output variable. We will need to write code to do that.
First, we should import certain Java packages. This will simplify coding later. Open the PriceAvailabilityQuote business process in the editor. In the editor, click anywhere in the white canvas area. This will deselect any activity and the Properties view will show the property of the process. Click on the Java Imports tab in the Properties view. Add these import statements.
import com.ibm.websphere.bo.BOFactory; import com.ibm.websphere.sca.ServiceManager;
Add a new snippet activity below the PrintRequest snippet activity. Change its name to PrepareResponse.
As the Java code for thie newly created snippet, enter the following.
BOFactory bofactory = (BOFactory)ServiceManager.INSTANCE.locateService("com/ibm/websphere/bo/BOFactory"); Response = bofactory.create("http://SimpleModule/types", "QuoteResponse"); Response.setString("QuoteID", "123456"); Response.setString("ProductSKU", Request.getString("ProductSKU")); Response.setString("StatusCode", "ITEM_AVAILABLE"); Response.setDouble("UnitPrice", 100.00); Response.setString("Currency", "USD");
The crucial line from the code above is:
Response = bofactory.create("http://SimpleModule/types", "QuoteResponse");
This creates a new business object instance and initializes the Response process variable. The create method takes as argument the namespace and the type name.
Test the Process
Restart the SimpleModuleApp. If publishing fails, take the steps mentioned before.
Right click anywhere in the assembly editor and select Test Module. Choose the PriceAvailabilityQuote component as before. Enter some values for the request fields. Click on Cont**inue**.
Make sure that the response object shows correct values in various fields.
You can download the fully completed project as a project interchange format from this link.
In this tutorial, we learned how to:
- Define your own complex data types. The business object editor lets us define XML schema elements without knowing anything about XML schema.
- Define your own interface (or WSDL portType elements). Once again, the tool significantly simplifies the process.
- Create a new BPEL process that implements the interface.
- Read fields from the input data.
- Create the output object and set various feilds.
- Test a process by entering fields of complex data typed objects.