 | Level: Introductory Richard Gregory (gregoryr@ca.ibm.com), Staff Software Developer, IBM Greg Adams (Greg_Adams@ca.ibm.com), Distinguished Engineer, IBM Jane Fung (jcyfung@ca.ibm.com), Advisory Software Developer, IBM Randy Giffen (Randy_Giffen@ca.ibm.com), Senior Software Developer, IBM
19 Apr 2006
Important: This article has been updated for WebSphere Integration Developer V6.0.2. This is the third in a series of articles exploring a service-oriented approach to application integration using IBM® WebSphere® Integration Developer. The first article provides an overview of WebSphere Integration Developer. The second article shows how to define black box services and connect them together to form a service-oriented architecture for a simple order processing application. This third article guides you through the implementation of those services. At the end of the article, you will have completed an order processing application.
Introduction
The
previous article
in this series covered the basic concepts of WebSphere
Integration Developer and its suite of tools. In that article,
we also saw the main steps to building an order processing
application (OrderProcessing) using a service-oriented
architecture. At this point, you probably wish you had read
that last article, or perhaps you read it, but had not consumed
enough coffee to remember the details. Fear not, we'll do a
quick recap to set the stage before diving into the details of
how to implement the services of our application.
The order processing application (OrderProcessing)
receives order information from an external client. It
then checks whether the client is in good standing (and
ideally fabulously wealthy) and, if so, forwards the
order to the shipping department. When the shipping
department confirms that the order has been shipped, a message
is printed.
To implement this application, we need a business object
representing the order information. The business objects are
sometimes referred to as the currency of the application, because
all of the services use them. Speaking of services, we will
also need services to receive the order, check the customer
information, and ship the order. These services are represented
by the three dark blue boxes in Figure 1.
Figure 1. A simple order processing application
In the previous article, you learned that we could define each of our
services and wire them together without actually knowing
the implementation details of any of the services. To do
that, we created a module (OrderProcessing Module), and then
created each of the services. Next, we identified the
interfaces that each service would support, and each interface from another service that
that they planned to call. Finally, we
wired the services together based on which service had
to call which other service. This approach is extremely
useful because it allows us to lay out an entire
application, top-down, without having to worry about the
implementation of each service until the entire
architecture is designed. In fact, we can have one user
lay out the overall service-oriented architecture, and a
team of people each implementing one of the services
based on the contract (interfaces) that the architect
specified.
What will you learn?
Now that we have refreshed our brains on the basic
structure of our order processing application, it is time
to roll up our sleeves and build it.
In the sections that follow, you will learn how to do:
-
Create a module to hold all the
artifacts that you will be authoring.
-
Create a business object to represent a
customer order.
-
Create components and their interfaces.
- Wire together the components.
-
Specify the implementations of these
components.
-
Deploy and test what you have built in
the WebSphere test environment.
Creating the OrderProcessing module project
To begin constructing the application, we
need a project to hold the business objects, components,
and interfaces. The type of project we will create is a
service assembly module project, or module project for
short. This is a special type of project that is aware
of the different types of artifacts (business objects,
components, and so on.) and can be deployed and
run on the WebSphere Process Server.
The module project corresponds to the large outer blue
box in Figure 1. Notice that all of the components,
interfaces, and wires are contained inside the large
blue box, and hence will be contained inside our new
module project.
Enough chit chat, let's actually do it!
 | |
Tip: If you have something selected in the view,
the pop-up menu shows only what is relevant for the
current selection, so you may need to click New >
Project > Module from the pull-down menu.
Tip: When you open the WebSphere Integration Developer
workbench for the first time, the Business Integration
perspective will open, with the Business Integration
view in the top left of the workbench
|
|
-
Ensure that the Business Integration perspective is
open.
-
Right-click the Business Integration view and select
New > Module.
-
In the New Module wizard, enter
OrderProcessing
for the Module name.
- Click Finish.
WebSphere Integration Developer creates a
project named OrderProcessing, as shown in Figure 2. You
might remember (or maybe not) the different types of
components discussed in
the previous article
in this series.
The Business Integration view categorizes your components
based on their type: process components, state machine
components, and so on. Similarly, it
categorizes your resources by type: your business objects are
under Data Types and the interfaces for each component are under
Interfaces. The category-based structure of the Business
Integration view makes it easy to find artifacts of a specific
type. The Business Integration view also provides several other
options for sorting and navigating your artifacts.
Figure 2. The OrderProcessing project
Creating the Order business object type
In this section, we'll create a business object to hold the order information. The Order business
object will be passed between the components as they
perform our business logic. The Order business object
will contain the following attributes:
- Order number,
- Product ID,
- Quantity being ordered
- Identifier of the customer who placed the order
The product ID and customer ID can contain alphanumeric
data and, therefore, will have a string type. The order number
and quantity will have an int type because they will
contain only integers.
To create the Order business object, follow these steps:
-
Right-click the Data Types category in the
OrderProcessing project, and select New >
Business Object.
-
In the New Business Object wizard,
enter
Order in the Name field, leave the defaults
for the rest of the fields, and click
Finish.
Now that we have our business object, it is time to create some
attributes to hold the order information. Creating attributes is quick and easy:
-
Ensure that the Order business object is selected
in the Business Object editor. It gets selected by
default when we created the business object.
-
To create our four attributes, right-click
the Order object and select Add Attribute.
Repeat that three more times.
-
Select attribute1, which is the first default name, and replace it with
orderNumber. Click the default
string type and select int from the types list.
-
Rename attribute2 to
quantity and
change its type to int.
-
Rename attribute3 to
productID and
leave string as the type.
-
Rename attribute4 to
customerID and
leave string as the type.
- Save your changes.
 | |
Tip: If the Properties view is not open, you can open it by
right-clicking any project artifact and selecting Show in
Properties.
|
|
Before closing the editor, let's take a closer look at
it. The top portion of the editor (see Figure 3) displays the
main elements of the business object. We can use this area to
edit common properties of the business object, including the name
and type of each attribute. The editor uses the Properties view
to show more advanced properties of the business object and its
attributes. For example, we can only restrict the set of
allowable values for an attribute in the Properties view.
Figure 3. The completed Order business object type
When you are finished enjoying the fine selection of properties
afforded by the Properties view, close the Order business object
editor.
Before we move on, take a quick peek at the Business Integration
view (typically in the top left corner of the workbench). You should be
able to see the new Order business object under the Data Types
category. Our application now has its currency.
Creating the components and interfaces
It's time to create our components (services) and define the
interfaces that they will support as well as other component's interfaces that they will call.
We will implement the following components and interfaces:
- ProcessOrder component and interface
- CustomerCheck component and interface
- ShippingProcess component and interface
- ShippingTask component and interface
- CustomerInformation import
- OrderProcessing export
The ProcessOrder component
We start by creating our
OrderProcessing component (see Figure 1) to receive the order
and begin working on it.
 |
Step 1 update. In WebSphere Integration Developer V6.0.2.2, double-click Assembly Editor, rather than OrderProcessing, under the OrderProcesing project. |
|
-
In the Business Integration view, open the assembly
editor by double-clicking OrderProcessing under the
OrderProcessing project.
-
Right-click the assembly editor and select Add Node -
Component (with no implementation type).
-
Right-click the component that we just created and
select Rename. Change the name Component1 to
ProcessOrder.
Figure 4 shows the completed ProcessOrder component. The
warning symbol
is displayed because there is no implementation for the
component yet. Don't panic, we don't know exactly how we will
implement the component, nor should we care. We are still trying
to sort out the pieces of our application and identify what they will do
in the grand scheme of the application universe.
Figure 4. The ProcessOrder component
At this point, you need to ask yourself, "Alright, what does
this component need to be able to do?" As we described in the
application overview, the ProcessOrder component places an order
based on the order information that it receives. When the order
has been shipped, the component prints out a message. This means
that we have to be able to tell this component to place an
order, and we have to be able to let it know the order has been
shipped. Capturing this requirement is easy; we simply need to
create an interface for the component and identify the two
operations that it will support.
The ProcessOrder interface
The ProcessOrder interface has two operations, placeOrder and
orderShipped. Both operations take an Order business object as
input. There is no value returned from placeOrder because we
only need it to kick off the ordering. Similarly, the
orderShipped operation does not return any values because it
only needs to print out a message when it is told that the order
has shipped.
To create the interface for the ProcessOrder component, follow these
steps:
-
Right-click the Interfaces category in the
OrderProcessing project and click New - Interface
-
In the New Interface wizard, enter
ProcessOrder for the
name, and leave the other default values.
- Click Finish.
-
In the interface editor that opens, right-click and
select Add One Way Operation.
-
Select the default operation1 name and replace it
with
placeOrder.
-
 |
Step 6 update. In WebSphere Integration Developer V6.0.2.2, this step is not necessary since one input is created by default for you.
|
|
Right-click the placeOrder operation and select Add
Input.
-
Change the name input1 to
order, then click the Type cell
where it says string. As Figure 5 shows, a type list
opens, including the Order type that you created
earlier. Select Order for the type.
Figure 5. Creating the ProcessOrder interface
-
Add another one-way operation, and then change the name
operation2 to
orderShipped.
-
 |
Step 9 update. In WebSphere Integration Developer V6.0.2.2, as in step 6, the input is already there. This is true in upcoming sections where you create interface operations. In request-response operations, one input and one output is created for you.
(There's a few more steps later where you can omit the "add input" step, but we won't keep reminding you unnecessarily.) |
|
Add an input to the orderShipped operation, rename it to
order, and then select Order for the type.
In the preceding steps, we chose One Way Operation. There are two
operation choices; one-way and request-response. A one-way
operation corresponds to when you don't expect your service to
return a result. Request-response is when you want a two-way
communication with the service, such as when you need to send a
query and get information back, or when you want to send a
message to kick off an action, but you need a response to know
if it was successful.
Now you can give the ProcessOrder component its interface:
-
Switch back to the assembly diagram, right-click
the ProcessOrder component, and select Add -
Interface
-
Select ProcessOrder from the list of interfaces.
We now have our first component specified. Notice that we still have
not actually implemented it; we have only identified what it
will do for us. Let's move on to the next component.
The CustomerCheck component and interface
The next component that we'll create is CustomerCheck. This
component's job is to receive the customer ID and confirm that
the customer is in good standing. That means that when we define its
interface, it will need an operation called checkCustomer. We will
need that operation to return information about whether the customer
is in good standing. Follow these steps to create CustomerCheck:
-
Switch back to the assembly diagram and create the CustomerCheck component in the same manner
as the ProcessOrder component.
-
Create a new interface by repeating steps 1 to 3 in
the previous section where we created the
OrderProcessing interface, and name it
CustomerCheck.
Now that you have the interface, let's add our operation to check
the customer standing:
-
In the interface editor, right-click and select Add
Request Response Operation.
-
Change the name from operation1 to
checkCustomer.
-
Add an input, change the name to
customerID, and leave
the type as string.
Notice that we did not pass the entire Order to this component.
That's because the component only needs to be aware of the
customer ID to check the customer's standing. Let's
make sure the operation returns whether the customer
is in good standing:
-
Add an output by right-clicking and selecting Add
Output. Change the name to
customerOK and select boolean for the type.
-
Switch back to the assembly diagram, and add the
CustomerCheck interface to the CustomerCheck component
in the same manner as when you added the interface to
the ProcessOrder component.
Figure 6 shows the completed CustomerCheck interface.
Figure 6. The completed CustomerCheck interface
Since the ProcessOrder component uses the service that
CustomerCheck provides, we need to wire ProcessOrder to
CustomerCheck.
-
Use your mouse to hover over the edge of the ProcessOrder
component. A yellow handle displays. Click
the handle and drag it to the CustomerCheck component.
-
 |
Step 2 update. In WebSphere Integration Developer V6.0.2.2, the Add Reference dialog box does not open since all the information to create the reference can be determined automatically. |
|
You will be prompted to create a matching reference
on the source node (ProcessOrder). Click OK, and then
select CustomerCheck for the interface in the Add
Reference dialog box.
Recall that when a component makes a service call to other
components, it does so using a reference. In the last step, a
reference was created automatically for you.
The ShippingProcess component and interface
The next component to create is ShippingProcess, which provides
another service that the ProcessOrder component needs. This
component is responsible for coordinating the shipping of the
order and notifying the shipping department to assign a
specialized shipping droid to the order. To accomplish this, we
need the ShippingProcess component to support an interface with an
operation that handles shipping the order.
-
Create a component named ShippingProcess in the same
manner as the previous ones.
-
Use your mouse to hover over the edge of the ProcessOrder
component and drag the handle to the ShippingProcess
component that you just created. When the prompt asks you to
create a matching reference, click OK.
-
You haven't created the interface for the
ShippingProcess component yet, so instead of selecting
an existing interface, click New in the Add
Reference dialog.
-
In the New Interface wizard that opens, enter
Shipping for the name and click Finish. This closes the
wizard and brings you back to the Add Reference dialog.
-
The Shipping interface that you just created is
selected by default in the Add Reference dialog, so just
click OK.
Time to catch our breath and see what we just did--the steps
sure didn't seem like the previous component!
Well, we created our new component and immediately wired an
existing component to it. WebSphere Integration Developer very helpfully made
a new reference and interface on the fly
for you. You didn't have to first run off and make the
interface; instead, WebSphere Integration Developer made an empty
interface for you, so you could continue your work and then come back and fill
in the interface later.
Let's do that now. The Shipping interface needs a one-way
operation, shipOrder, which takes an Order business object as
input. The operation sends a message to the Shipping
department component so that the shipping department knows to send
the order.
To create the operation, follow these steps:
-
In the Business Integration view, under the Interfaces category,
double-click the Shipping interface. This opens
the Shipping interface in the interface editor.
- Add a one-way operation named
shipOrder.
- Add an input named
order, with the type set to Order. Figure 7 shows the completed Shipping interface.
Figure 7. The shipping interface
-
When the shipping process completes, it needs to send a message
back to the OrderProcessing component to notify it that the
order is complete. Therefore, you need another wire from
ShippingProcess back to the ProcessOrder component.
Connect the ShippingProcess component to the
ProcessOrder component and click OK to create the
reference.
That's all there is to it because ProcessOrder already has an
interface.
The ShippingTask component and interface
Next, we'll create the ShippingTask component and its interface.
ShippingTask provides a service for the ShippingProcess
component to call when it wants to create a task that a human
must complete (or in our case, a specialized shipping droid).
The ShippingTask interface needs one request response operation,
shipOrder, which takes an Order business object as input. The
operation is used to send the order data to someone (the
friendly droid) in the shipping department who will ship the
order. The order data is returned from the ShippingTask. In the
future, we might want to have the shipping task modify the order
before returning it, perhaps to indicate the quantity that was
actually shipped.
To create the human task component and its interface, follow
these steps:
- Create another component called
ShippingTask.
-
Connect the ShippingProcess component to the
ShippingTask component, click New to create an
interface, and then name it
ShippingTask.
-
Click Finish in the New Interface wizard, and then
click OK in the Add Reference dialog.
-
Open the ShippingTask interface and add a request
response operation named
shipOrder.
-
Add an input named
order, with the type set to Order.
-
Add an output named
completedOrder, also with its type
set to Order.
Figure 8 shows the completed Shipping interface.
Figure 8. The ShippingTask interface
Hopefully by now you are getting the idea that laying out the
service-oriented architecture of your application is pretty
quick and easy. It's a matter of dragging your services
(components) to the canvas, defining what you want them to do,
and connecting the boxes together. You can probably do it with one arm tied behind your back,
and without coffee!
The CustomerInformation import and OrderProcessing export
The main parts of the OrderProcessing module are now complete.
All that is left is to connect it to the outside world. In
this section, we will show you how to add an import and an export to do just that.
-
The import will allow the CustomerCheck component to
use the services of an external customer information
system.
-
The export will allow an external client to send the
order information to the ProcessOrder component.
The CheckCustomer component needs to call an external
information system, which contains all of our customer data. To
connect to an external system, we must use an import. An import
indicates that instead of calling another component in the
module, we will be calling something that is outside our
immediate application--something that we are trying to
integrate with the overall service-oriented integration
solution.
Recall from
the second article
that an import contains a binding that
points to the actual external implementation. Perform the
following steps to create the import. Then, in the implementation
section of this article, you will create a binding.
-
In the assembly editor canvas, right-click the canvas and
click Add Node > Import.
-
Change the name to
CustomerInformation.
-
Right-click the CustomerInformation import, click
Add Interface, then select CustomerCheck from the list
of interfaces (you created it with the CustomerCheck
component).
-
Connect the CustomerCheck component to the
CustomerInformation import.
Before we move on, it's worth noting that we used the same
interface for CustomerCheck and CustomerInformation. This is
because CustomerCheck will receive the customer ID, do some
business logic, and then call the external system with the same
ID and the same type of operation--namely to check if the customer
is valid. We could also have used different interfaces for the
component and the import--but for simplicity in this article, we
have opted to make use of the same interface.
As discussed in
the second article,
an import must be bound to another
module, Web Service, Java™ Message Service(JMS) destination,
or EJB component. Using the
integration test client, you can still test the module even
without defining the import binding. Therefore, for simplicity, you can
omit selecting a binding.
To create the export, you need to do the following step:
-
 |
Update to create the export step. In WebSphere Integration Developer V6.0.2.2, the menu selection is Generate Export - SCA Binding. |
|
Right-click the ProcessOrder component and click
Export - SCA Binding.
This step creates an export for your component,
allowing it to be called from an external source. The binding
you choose depends on how you plan to access the component. An
example of using an export can be found in
Building SOA solutions with the Service Component Architecture -- Part 1,
which describes invoking a component using a JSP.
Your completed assembly should look similar to that shown in
Figure 9. The application skeleton is now complete. Next, you
will define the implementation for each component.
Figure 9. The completed OrderProcessing assembly
Implementing the ProcessOrder component
Although we've laid out the component topology, we've not yet
said how any of the components will be implemented. Getting
started with an implementation is simple; you just select a
component and pick an implementation type for it. WebSphere
Integration Developer will create a skeleton implementation and
your job is simply to fill in the business logic.
We've decided to implement the ProcessOrder component with a
business state machine. A business state machine is a special
type of business process because it is event driven, and its
actions depend on the current state of the process. In our case,
we will use it to model the state of the order as it progresses
from arriving, to shipping, to shipped.
-
Right-click the ProcessOrder component in the
assembly editor and click Generate Implementation -
State Machine.
-
A dialog opens asking in which folder the state
machine should be placed. Ensure OrderProcessing is
selected and click OK.
The State Machine editor opens with a trivial state machine. As
Figure 10 shows, there is an error marker on the transition from
the initial state to the first state because there is not yet an
operation to trigger the transition. In other words, we need to
identify the operation that gets the state machine rolling.
Figure 10. The newly created ProcessOrder businesss state machine
Notice the references on the right: these were added automatically
when the state machine was created, based on the references
you added to the ProcessOrder component. You will use those
to make calls to other services.
First, we will rename the initial and final states to something more appropriate.
-
In the State Machine editor, click the default
name of State1, and replace it with
CustomerBeingChecked.
-
In the same manner, change InitialState1 to
WaitingForOrder.
- Rename FinalState1 to
OrderComplete.
Now let's add some more states to help us keep track of when we
are checking the customer and when we are busy shipping the
order.
-
Right-click the canvas and click Add > State,
then click the canvas to add the new state.
- Rename State2 to
OrderBeingShipped.
-
Right-click the CustomerBeingChecked state and
select Add - Transition.
-
When the line displays under the cursor, click the
OrderBeingShipped state. This creates a new transition
from CustomerBeingChecked to OrderBeingShipped.
-
In the same manner, add a transition from the
OrderBeingShipped state to the final state.
Your state machine should now look similar to the one shown in
Figure 11, depending on where you put each state. The easiest
way to think of this is to keep in mind that the state machine is
literally trying to model the states that your application is going
through as it processes the order. The application is either
waiting for an order, checking the customer, shipping the order,
or the order is completed.
Figure 11. The ProcessOrder component states
In the next set of steps, we define the triggers for the
transitions between the states. First, we set up the
transition that occurs when we are told the order has been
shipped:
-
Right-click the transition between
OrderBeingShipped and OrderComplete and select Add
Operation.
-
Right-click again on the same transition and select
Show in Properties.
-
In the Properties view that opens, select
ProcessOrder in the Interface list, and then
select orderShipped in the Operation list.
This means that when the orderShipped operation of
the ProcessOrder component is invoked, it triggers the transition between OrderBeingShipped and OrderComplete.
-
Next stop on the transition tour is to handle when we
receive notification that an order needs to be handled.
With the Properties view still open, select the
WaitingForOrder to CustomerBeingChecked transition,
select ProcessOrder in the Interface list, and
select placeOrder for the operation.
There are two transitions coming from CustomerBeingChecked. One
transition will be associated with a customer in good standing, in which
case we can ship the order. The other transition will be for the
customers we find to be somewhat undesirable. In that case, we want
to wrap up the order and bid the customer a nice day.
A transition does not have to occur based on the state machine
component receiving a message. Transitions can also happen
automatically based on other criteria. In this case, we will base
the transitions on the customer's standing.
-
You first need a variable to hold the result of the
customer information check (that is, the customer standing).
Right-click the Variables section to the right of the
state machine editor and click Add Variable.
-
In the Data Type Selection dialog that opens, enter
isCustomerOK for the variable name, and select
boolean from the list of types.
Next, we'll define the transition for a customer in good
standing whose order we will ship. To help you to write your
action, WebSphere Integration Developer includes a visual snippet
editor. Let's use that to write our code for filling our
order and ID variables, and for printing some information to the
log.
-
Make sure the Properties view is still open (if it isn't,
click the Properties view at the bottom of the
workbench), and select the CustomerBeingChecked to
OrderBeingShipped transition.
-
By default, the transition type is set to
Automatic, which is what you want. Click the
Condition tab of the Properties view, and then click
Create.
-
In the visual editor that opens, click the
isCustomerOK variable on the right and drag it onto the
editor canvas.
-
Right-click the canvas and click Add - Return,
and then click the canvas again.
-
Right-click the isCustomerOK variable on the
canvas, select Add - Link, and then click the return
expression.
-
Change the name of the condition from Condition1 to
Good Customer and save the editor contents.
These steps create an expression that returns true or false for the
condition depending on the value of isCustomerOK. When the
condition evaluates to true, the transition will occur. Note
that there will be an error marker indicating that "the
transition will not occur because another transition will always
occur." We'll fix that next.
The next set of steps deal with customers in bad standing
and remedy the error marker.
-
Select the transition between CustomerBeingChecked
and OrderComplete, then right-click and select Add -
Condition. Ensure the Details tab of the Properties view
is open.
-
Repeat steps 3 to 6 in the preceding list, except this time change the
condition name to
Bad Customer. This creates the
same expression as the Good Customer condition.
-
Click the Invert Result check box, because you want
this transition to fire whenever isCustomerOK is false
(that is, the opposite case to the Good Customer
condition).
Now you have all the states and transitions in place. The next
step is to define the actions that are supposed to happen in
each state. The information you need to process an order is
contained in the input to the placeOrder operation.
You need to store the order information in a variable so that you can
pass it to the services that are called as the state machine
processes an order. You will also need to store the customer ID
that the order contains in another variable, so that you can pass it
to the customer check component.
The next steps will create and assign values to those variables
along with a logging statement so you can see what is
occurring as the machine runs.
-
Add another variable by right-clicking the
Variables section and selecting Add Variable. Enter
myOrder for the name, and select Order as the type.
-
Create one more variable called
myCustomerID with
string as the type.
Now we need to create the actions on our transitions and make
use of those variables.
-
Right-click the transition between WaitingForOrder to
CustomerBeingChecked and select Add - Action. This action
lets you define what happens when the transition
occurs (which is a result of calling the placeOrder
operation).
-
Change the name in the Properties view to
Print info
and set variables.
We'll use the visual snippet editor again to define the
action:
-
To begin defining the action, click the Details tab.
-
Right-click the canvas and select Add -
Expression, and then click the canvas.
-
In the expression
box, enter the text
"Order has been placed. Setting
Variables." (including the quotes).
-
Right-click the canvas and select Add -
Standard, and then select Utility - Print to log.
-
Click the
canvas, and then connect the string expression to the
log expression by right-clicking the text expression,
selecting Add - Link, and then clicking the Print to
log utility.
-
Drag the placeOrder_Input_order variable to the canvas
(this will
contain the input that is received when the placeOrder
operation is called).
-
Drag the placeOrder_Input_order variable, and
then click at the end of the variable name, which
displays a list. In the list, expand placeOrder_Input_order
and select customerID.
-
Drag the myOrder variable to the canvas, and then
connect placeOrder_Input_order to it. This assigns
the order data received to the myOrder variable.
-
Drag the myCustomerID variable to the canvas, and
then connect placeOrder_Input_order.customerID to it.
The details should now look as in Figure 12.
Figure 12. The Print info and set variables action
The next step is to call the service that checks the customer
information when the order enters the CustomerBeingChecked
state. To do that, we will use one of the references that was
automatically created for us. Remember that this is a reference
to the other component. We will use the variables that we created
earlier.
-
Right-click the CustomerBeingChecked state and
select Add - Entry.
-
Change the entry name to
Check Customer. In the Details tab of the Properties view, click
Invoke . Click Yes when the message comes up informing you
that you will lose any changes.
-
Select CustomerCheckPartner from the Reference
list. This reference was created when
you created the wire from the ProcessOrder component to
the CustomerCheck component.
-
Select the checkCustomer operation from the Operation
list. This is the only operation in the CheckCustomer interface.
-
In the Variables box, select myCustomerID, and in the
Operation Input box, select customerID
-
Click Set. You have just specified that
the input to the checkCustomer operation comes from
the myCustomerID variable.
-
To assign the return value of the service,
which is a boolean value, to
isCustomerOK, click the Output parameter button, then
click both customerOK in the Operation output box and
isCustomerOK in the Variables box. Click Set.
The entry for the state should now look like Figure 13.
Figure 13. Service call in the entry for the CustomerBeingChecked state
The next step is to add the service call to the shipping
component when in the OrderBeingShipped state. The steps are the
same as those for creating the entry action for the CustomerBeingChecked
state:
-
In the same manner as the previous steps, right-click
on the OrderBeingShipped state, select Add - Entry,
change the name to
Ship Order, then select Invoke for
the implementation. Click Yes when the message informs
you that you will lose any changes.
-
For the Reference and Operation, select
ShippingPartner and shipOrder respectively.
-
For the shipOrder input, select myOrder and shipOrder
in the Variables and Operation input lists
respectively, and then click Set. The operation is one-way,
so there is no output to set.
You may have noticed that as you were building the state
machine that there was one error all along: Correlation set must
have at least one property. When deployed to a server, your
state machine could have several instances, each in a different
state. When an operation is called on the ProcessOrder
component, you need a way to make the call on the
correct instance. This is accomplished using correlation sets. A
correlation set tells the state machine which running instance
to use for the given input data. It does this by examining
the contents of the input data, using a specified field as a
kind of key that uniquely identifies the corresponding process
instance.
In the OrderProcessing state machine, the order number
will determine which instance to use. Correlation sets will be
covered in more detail in a future article covering business
processes.
-
Click anywhere on an empty area of the state machine
editor canvas, select Show in Properties and select the
Correlation tab.
 |
Update to steps 1 through 7.
In WebSphere Integration Developer V6.0.2.2, the seven steps to create the correlation set are replaced with these four steps:
- Right-click Correlation Properties on the top-right corner of the editor and select Add Correlation Property.
- Enter OrderNumber for the name, select int for the type, and then click OK.
- In the OrderNumber correlation properties that opens, each operation of the business state machine displays. Click the cell next to placeOrder and then drill down to Order - orderNumber.
- Click the cell next to orderShipped and drill down to Order - orderNumber.
|
|
-
Click New and, in the Edit Correlation Property
dialog that opens, enter
OrderNumber for the name.
-
Click Browse and select int for the type.
-
Click New next to Aliases. This opens the Property
Alias Selection dialog.
-
At the bottom of the dialog expand placeOrder input,
drill down to orderNumber, select it, and then click
Add.
-
Click New again and expand orderShipped input, drill
down to orderNumber, select it, then click OK.
- Click OK to complete the correlation set.
You have just indicated that the orderNumber attribute of any
Order business object used as input to either operation is an
alias for the OrderNumber correlation. This means that the
orderNumber contained within the Order business object will
determine which instance of the state machine will receive the
placeOrder message.
That completes the ProcessOrder component. For simplicity, we did not include error
handling for cases such as an invalid operation called for the
current state. You can
just add a few more print statements so that when you test the
application, you can see what is occurring as the state machine
executes:
-
Right-click the Bad Customer transition, select
Add - Action, and then change the name to
Print Info.
-
In the property Details tab, right-click the
canvas, select Add - Expression, and then drop a new
expression on the canvas. In the expression box, enter
"Order has been rejected." (including quotes).
-
Right-click the canvas again and select Add -
Standard, and then select Utility - Print to log.
-
Click the canvas, and connect the string expression
to the log expression.
-
Repeat the previous steps to create another action named
Print Info for the orderShipped transition that prints
"Order has been shipped." and for the Good Customer
transition that prints "Order will be shipped."
-
Add one last entry action named
Print Info to the
OrderComplete state that prints "Order is complete."
The completed ProcessOrder state machine should now look similar
to the one in Figure 14.
Figure 14. The Completed OrderProcessing business state machine
Implementing the ShippingProcess component
The next component to implement is ShippingProcess. You will
implement it using a business process that invokes the
ShippingTask component, and then calls the orderShipped
operation on the OrderProcessing component to indicate that the
order has been shipped. Business processes will be covered in
detail in a future article in this series.
-
Open the OrderProcessing assembly editor, and then
right-click the ShippingProcess component and select
Generate Implementation... - Process.
-
When the dialog box opens and asks where to put the
process implementation, click OK to accept the default.
The business process editor opens, as shown in Figure
15..
Figure 15. The ShippingProcess business process
Often when creating a business process, you might find it
helpful to lay out the structure of all of the activities but not
worry about their details (just as it is when you create your
module assembly diagram). After you have the activities you can
then loop back and fill in more details. Let's try that approach
now by creating a couple of activities that will wake up the
shipping droid and then notify the process order component when
shipping is complete.
-
Right-click the canvas and select Add - Invoke,
and then change the name of the Invoke activity to
ShippingTask.
-
Repeat this to add a second invoke named
NotifyShipped.
Let's go back to the two activities we just created and fill in
some details.
-
Select the ShippingTask activity and open the Details
tab in the Properties view.
-
Click Browse next to Partner and select
ShippingTaskPartner.
-
As with the state machine, the partners available depend on the
references in the assembly diagram; there is one partner for
each reference. There is only one operation for the ShippingTask
operation, so it will appear in the Operation list.
Ensure that the Use Data Type Variables check box is selected,
and then, for both the Input and Output variables, click
the selection button to the right of each variable and
select Order for the variable.
-
In the same manner, select the NotifyShipped
activity, browse to ProcessOrderPartner in the property
details, and select the orderShipped operation. Also, set
the variable to Order.
The completed ShippingProcess is shown in Figure 16.
Figure 16. The completed ShippingProcess implementation
Now, when the shipOrder operation is called, it sends a
message to someone in the shipping department to ship the order
by calling the shipOrder operation of the ShippingTask
component. When the task is complete, the NotifyShipped activity
will call the orderShipped operation on the ProcessOrder
component, which will trigger a transition to the OrderComplete
state.
Implementing the ShippingTask component
The Shipping Task component is simply a Web page that presents
the order information and allows a shipper to indicate that the
order was shipped. In this case, we will choose a human task
implementation:
-
In the OrderProcessing assembly editor, right-click
on the ShippingTask component, and then
select Generate Implementation... - Human Task.
-
When the dialog box opens and asks where to put the
implementation, click OK to accept the default. Also,
accept the default name for the Human Task Component
Handler dialog that opens.
You are now done with the ShippingTask component implementation!
The default settings are sufficient for this example, and since
you will not be enabling server security, the default
authorization settings are fine.
This means that anybody who opens the Business Process
Choreography explorer on the server can view and respond to
pending shipping tasks. The Business Process Choreographer
explorer and human tasks will be covered in detail in
a future article in this series.
Implementing the CustomerCheck component and CustomerInformation
import
You implement the CustomerCheck component using a set of
business rules, which in this example, consists of two rules.
The rule is simply that a customer whose identifier begins with
"gold" is automatically considered a good customer; otherwise it runs a
customer check. Authoring of Business Rules, and how to
easily change them after deployment, will be covered in a future
article in this series.
To implement the CustomerCheck component, follow these steps:
-
In the OrderProcessing assembly editor, right-click
on the CustomerCheck component and click Generate
Implementation... - Rule Group. When the dialog box opens
and asks where to put the implementation, click OK to accept
the default. A new rule group displays, as in Figure 17.
Figure 17. CustomerCheck rule group
-
Select checkCustomer, and then select Enter
Destination next to the Default Destination and select
New Ruleset. For the name, enter
checkCustomer and click Finish. A RuleSet editor will open.
-
Right-click Rules and select Add If-Then Rule
twice to add two rules.
-
In Rule1, in the If cell, click Condition, and then type
customerID.startsWith("gold") == false.
You can also
select each part of the expression from the
lists that display as you type.
-
In the Then row of the table, click Action and
select Invoke.
-
In the cells that appear within the Then row, select
CustomerCheckPartner for Partner, checkCustomer for
Operation, customerID for the customerID input, and
customerOK for the customerOK output. This means that
the input received by way of the customerID parameter is
passed as the customerID parameter of the checkCustomer
operation of the CustomerInformation import. Likewise
for the customerOK output parameter.
-
In Rule2, in the If cell, enter
customerID.startsWith("gold") == true and in the Then cell, enter customerOK = true.
The completed ruleset is shown in Figure 18.
Figure 18. The checkCustomer operation ruleset
For the CustomerInformation import, you will just leave it as an
unbound import; that is, it is not set up to call any
implementation. In the next article in this series, you will
bind imports in one module to exports in other modules.
You have now completed the module, so in the next section you
will deploy and test it.
Testing the OrderProcessing module
Now you can test the OrderProcessing application to see how it
works by following the last set of steps. All of the necessary
deployment code has already been generated behind the scenes as
you were saving the contents of the various editors.
 | |
Tip: To import an existing module into your workspace, select File - Import -
Existing Project. Then browse to the zip file
containing the Project Interchange file.
|
|
-
Verify that there are no errors by switching to the
Problems view. If you see any errors and do not know how
to fix them, you can cheat and load the
OrderProcessingPrebuilt module (you can download the
Project Interchange file from the downloads section at
the end of this article) and either test using that
module, or compare it to the module that you built.
-
Right-click the OrderProcessing module and select
Test Module.
-
In the test client that opens, select ProcessOrder
for the component and placeOrder for the operation,
because that is the kick-off operation
for the order processing. Recall that the calls to the
ProcessOrder state machine are correlated on the
orderNumber, so the value that you enter is important: the
same value must be used when the other ProcessOrder
operations are called. The other values are not used in
this example, so you can enter any values. For the
initial request parameters, enter
5 for the orderNumber,
abc for the productID, 1 for the quantity and 123 for
the customerID, as shown in Figure 19.
Figure 19. Testing the OrderProcess module
-
Click Continue, and after ensuring that a WebSphere
Process Server is selected in the deployment dialog box,
click Finish. You will need to wait while the server
starts (if it isn't started already) and while the
application deploys to the server.
After a few minutes, you will see events in the Events
pane of the test client as service calls are made between
components, as shown in Figure 21.
The first event displays at the
initial call to the placeOrder operation, which causes the
ProcessOrder state machine to transition to the
CustomerBeingChecked state. During the transition, the line
Order has been placed. Setting Variables. prints in the
console.
The next event shows the call from ProcessOrder to the
CustomerCheck component. Because the customerID was not prefixed
with "gold", the business rule triggers a call to the
CustomerInformation import, which ends up being emulated because
it is an unbound import. At this point, a manual emulate event
displays, as shown in Figure 21. The next set of steps
complete the emulation and then the human task, once it has
invoked the ShippingProcess component.
-
To complete the emulation for the checkCustomer
operation, enter
true for the value of the customerOK
output variable, then click Continue.
-
When the ShippingProcess
component calls the ShippingTask component, a human task
is waiting to be completed. Open the Business
Process Choreographer Explorer by switching to the
Servers view, right-clicking the WebSphere Process
Server instance, and selecting Launch - Business Process
Choreographer Explorer.
-
When the Business Process Choreographer Explorer
opens, the My Tasks page will be open by default. Select
the check box next to ShippingTask and select Work On.
The order information displays as in Figure 20.
-
Recall that the shipOrder operation of the
ShippingTask interface returns an Order business object.
Ensure that you enter the same value for the orderNumber, in
this case
5, so that the correct instance of the
ProcessOrder state machine receives the orderShipped
message. Any values for the other order properties are
sufficient because they are not used in this example.
- To complete the task, click Complete.
Figure 20. Completing the ShippingTask in the Business Process Choreographer Explorer
The ShippingTask activity is now complete and the NotifyShipped
activity executes. In the console, you will see the rest of your
print statements. More events appear in the test client as it calls the rest of
the services calls. Figure 21 shows the log and the completed test.
Figure 21. Testing the OrderProcessing application
Summary
In this article, you explored some of the basics of building an
application using WebSphere Integration Developer. You built
components based on interfaces that you created, provided simple
implementations for them, and then tested the application. In
future articles, you will learn how to use other WebSphere
Integration Developer tools to build a more substantial
application.
More articles in this series
Download | Description | Name | Size | Download method |
|---|
| Project interchange file | orderprocessing.zip | 24 KB | FTP | HTTP |
|---|
Resources Learn
Get products and technologies
Discuss
About the authors  | 
|  |
Richard Gregory is a software developer at the IBM
Toronto Lab on the WebSphere Integration Developer team.
His responsibilities include working on the evolution
and delivery of test tools for WebSphere Integration
Developer.
|
 | 
|  | Greg Adams was the lead architect for the user interface
in the award-winning Eclipse platform, and more
recently, has been the lead architect and development
lead in the core WebSphere Business Integration Tools,
including WebSphere Studio Application Developer Integration Edition
and WebSphere Integration Developer. Greg led the delivery of
IBM's first complete services oriented architecture
(SOA) tools stack and the first BPEL4WS standards
supporting Business Process Editor; both critical
deliverables in support of IBM's On Demand strategy. |
 | 
|  | Jane Fung is an Advisory Software Developer at IBM Canada
Ltd, where she is responsible for developing the Business
Process Execution Language (BPEL) and Business Rules
debuggers in WebSphere Integration Developer. Prior to
that, she was the team lead of the WebSphere Studio
Technical Support team.
|
 | 
|  | Randy Giffen is a senior software developer is the usability lead for WebSphere Integration Developer and WebSphere Message Broker Toolkit.
He was responsible for WebSphere Integration Developer's business state
machine tools and the visual snippet editor. Prior to to
this he was a member of user interface teams for
WebSphere Studio Application Developer Integration Edition,
Eclipse, and VisualAge for Java.
|
Rate this page
|  |