The Business State Machine (BSM) component in IBM® WebSphere® Process Server (hereafter, referred to as Process Server) provides a way to define and work with business "nouns". These nouns are things like "orders" or "trips" that have a lifecycle controlling their behavior. For example, the cancel operation on a trip will not be supported once the trip is completed, and will further need to process things differently for a trip that has been reserved versus one that has not. Business State Machine provides a way of developing, debugging, and monitoring these nouns as a state machine.
This series of articles provides an overview of Business State Machines, including an overview of its capabilities and a discussion of using BPEL processes as an alternative. We do this by building a vending machine. In each article, we enhance the vending machine by using more of the BSM capabilities. In the first article we examined some fundamental features of BSM, and showed how these concepts can be used to implement the most basic vending machine. We then tested it using the BPC Explorer. In this second article, we will make our vending machine collect money, introduce actions, and test it using component test. In the final article, we will extend the vending machine by making it dispense products, introducing conditions and timeouts, and testing it using the debugger. Finally, we will look at simplifying the state machine through the use of composite states.
In the last article, we create and tested the vending machine maintenance interface. This interface controls powering the vending machine on and off, shown in Figure 1.
Figure 1. The simple vending machine with power on and power off
Now that we can turn the vending machine on and off, it needs to be able to collect money.
We do this by adding a new state to the state machine called Collecting, as well
as two new operations to the state machine's interface: deposit
and coinReturn. We want to keep the maintenance interface separate
from the operational interface, so that we have more control over the exposure of the interface.
For example, we do not want to export the maintenance interface on the module containing the
vending machine, but still want to expose the operational interface. Thus, we create a new interface
in the interface editor, shown in Figure 2.
Figure 2. Interface operations to deposit and return money
The deposit operation is called when money is deposited into the vending machine.
The amount deposited is passed as depositAmount, which is the value in cents.
The coinReturn operation is used to return the money put into the machine.
The modified state machine is shown in Figure 3.
Figure 3. Vending machine with added Collecting state
Now when the vending machine is in the Running state, it can accept either
the powerOff or the deposit operation.
The deposit operation causes the transition to
the Collecting state. Once we are collecting money, we need to keep track of
how much money has been deposited. As shown in Figure 4, to do this we add the variable totalDeposited
to the BSM.
Figure 4. totalDeposited variable added to state machine
However, merely adding the variable is not enough. We also have to write some Java™ code that will
update the value as we move through the state machine. This is done by adding actions to the state machine.
One type of action is the transition action. Transition actions only occur if the transition is taken.
These actions are identified by the blue pinwheel, such as Update Total
on the transition we were just discussing. These actions can be either a Java snippet or an invocation of
another component. Right now we'll focus on Java snippets and return to invokes later.
For actions associated with a transition caused by an operation, the input and output parameters
are available as local variables. The pattern is <operation>_Input_<parameter>
and <operation>_Output_<parameter>. For example, in the case of the actions associated
with the transition caused by the deposit operation, the variables deposit_Input_serialNumber
and deposit_Input_depositAmount are available. Note that our examples do not have an output variable,
since these are only available when two-way operations are defined in the interface.
In the vending machine example, the following transition actions can occur:
- Initialize
- This action does any initialization needed for the vending machine. In this example we
set the
serialNumberof the state machine into a variable, which allows us to use the serial number when we print messages to the system log. - Update Total
- These actions add the deposited amount to the
totalDepositedvariable. - Return Money
- This action would do whatever processing is needed to return the deposited money. This is just a placeholder in this example.
- Shutting down
- This action would do whatever shutdown activity is needed. In this example, this is also just a placeholder.
For this example, we have also added code in each of these actions to print messages to the system log.
The other types of actions are the state entry and exit actions. These are actions that occur when a state is
entered (or exited) regardless of which transition caused the state to be entered (exited). These are shown
in the bottom part of the state and are identified with an arrow going into it (entry) or out of it (exit). In our example,
the Running state has an entry action called Zero Total.
This action sets the value of totalDeposited to zero whenever the
Running state is entered. In our example, Running could be entered either
because of the powerOn operation causing a BSM to be created,
or from a coinReturn operation when in the Collecting
state.
There are a few special cases for entry and exit actions. Because the action on the transition coming out of the intial state provides equivalent support, initial states do not support either. Final and terminate states support only entry actions, since these states are never exited. Entry actions are one reason that multiple final (or terminate) states would be specified for a state machine. For example, a state machine may have a final state that is reached as part of normal processing that doesn't have an entry action and a second final state that is reached due to the state machine being cancelled. This second final state could have an entry action that logs information about the cancellation.
Let's go back to the new transitions in the vending machine. We discussed the transition caused
by the deposit operation when the BSM is in the Running
state; however, the deposit operation is also valid when in
the Collecting state. This type of transition (where the source and target state
are the same) is called a self-transition. There are two types of self-transitions, and the difference is important
to how the state machine behaves. An internal self-transition is one where the state is never logically left, while
an external self-transition logically leaves and returns to the same state. In our current example, it does not matter
which self-transition method we use. However, if we had an entry (or exit) action on
the Collecting state this would be very important. For an internal self-transition,
entry and exit actions are not executed when the self-transition is taken; the state is never entered or exited,
so these shouldn't be run. On the other hand, for an external self-transition entry and exit actions would
be taken, since the state is left and subsequently returned to. There are other differences which we will discuss
later.
The last new transition is the one from the Collecting state caused by
the coinReturn operation. The addition of this transition creates a loop
between the Running state and the Collecting state;
the vending machine can transition an indeterminate number of times between these two states.
Getting the vending machine state
Often the user of the BSM will want to know the state machine's state.
For example we want to be able to find out if the vending machine is in
the Running state or in the Collecting
state. In order to do this, BSM supports the definition of two special operations
called getState and getDisplayState.
When one or both of these operations are defined, BSM will generate their implementation.
For the getState method, the implementation will return
the internal state name that the state machine is currently in. We make the distinction
that this returns the internal state name,
because this is not the state you see in the BSM editor. For example, the internal state name
for Collecting is State2.
Unfortunately there isn't anyway in the BSM editor to see this. In order to find out these
names you have to look at the SACL file as XML. To do this, close the BSM editor for the state
machine, right-click on the BSM, select Open With > Text Editor.
Figure 5. View state machine in text editor to get state name
Note that this selection sticks, so you will need to close the SACL file and select Open With > Business State Machine Editor to open it in the editor again.
Looking at the SACL file there is entry:
<sacl:state displayName="Collecting" name="State2"/>
This defines a simple state which internally is called State2 but will
be called Collecting when it is displayed. On the other hand, the
implementation for getDisplayState returns the displayName instead of the
internal name.
For either operation you should note that a state machine is never in the initial state (since it always immediately transitions) and is destroyed when it enters the final state, so these states will never be returned when calling these operations. In fact, calling this operation on a state machine that has reached its final state will return an exception. You should also note that these operations return the persistent state of the BSM and not the the dynamic state of the BSM. In other words, if the BSM has transistioned from Running to Collecting, but has not completed processing, the values for Running (State1) will be returned.
In order to have BSM generate support for the getState method, the
operation must be declared in an interface. In the vending machine example, we added it to the
maintenance interface, as shown in Figure 6.
Figure 6.
getState
operation added to interface
Notice that getState is a two-way operation. The input parameters are whatever
is needed for correlation and the output must be a single parameter called state of type string.
Specification of getDisplayState is the same except for the operation name.
Now when the vending machine is generated it will support the getState operation.
Getting the vending machine state
In the previous article, we tested the vending machine using the BPC Explorer. In this article we'll test it using Component Test. To use component test go to the wiring diagram, right-click on the vending machine component, and select Test Component. This brings up the screen shown in Figure 7, which will allow us to call operations on the vending machine.
Figure 7. Test the vending machine with component test
This article will not go into details on component test, since we are focusing on state machine testing.
The first thing we need to do is to create the state machine. This is done
via the powerOn operation on the maintenance interface.
Thus we need to change the interface and the operation using the drop downs shown in Figure 8.
Figure 8. Select the powerOn operation in component test
Component test will automatically fill in the parameters (and their types) for the selected operation. To execute the operation, simply fill in the serial number (123 in this case) and click the Continue button. You will be asked to select a server, which will be started automatically, if it is not already started. The operation will be invoked and this will appear in the events window, shown in Figure 9.
Figure 9. Starting a vending machine instance in component test
Also the logs in our actions will show up in the console:
Figure 10. Vending machine snippet logs
To call another operation, press the invoke icon in the upper right portion of the Events window, select the operation, fill in the data parameters, and click the continue button. Let's make our first deposit to the vending machine:
Figure 11. Deposit money in the vending machine
The result is that in the Events window:
Figure 12. Results in component test after deposit
And in the console we see:
Figure 13. Results in snippet logs after deposit
We can also call getState from component test:
Figure 14. Calling
getState
in component test
Since getState is a two-way operation, it has a response. This shows up as a
Return element in the Events section:
Figure 15. Return event from
getState
The Return element is immediately displayed in the properties section and shows the state returned
by getState:
Figure 16. Returned value from
getState
As described above, State2 is the internal state name for the Collecting state.
If we want to execute the same operation with the same parameter values, we can right-click an Invoke in the
Events window and select Rerun. This is especially useful for executing the getState
operation, since the input parameter doesn't change.
BPC Explorer versus component test
The BPC Explorer is always available, even in a production system, so it can always be used to work with a BSM.
It does, however, have a major shortcoming. Currently when calling an operation on a BSM, the return parameter
cannot be displayed. This means that the getState operation is of no value in that
environment. This will be addressed in future releases, but for now, if the return values are needed, then the
operation would need to be called via some other mechanism, such as a JSP or, if testing, via component test.
The major advantage of component test is that calls from the BSM can be easily monitored and emulated. For example, if the Return Money action called out to another component, we could test that the call is correctly formed and that the vending machine, could handle the response correctly, if a response existed. We will return to this in a later article.
In this article, we extended the vending machine to include the collecting money. This provided our first self-transition, the addition of variables, and actions. We then used the component test to test the updated vending machine. In the upcoming article, we will extend the vending machine by making it despense products and we will look at how to monitoring and debugging BSMs.
Learn
-
"WebSphere Process Server Business State Machines concepts and capabilities, Part 1: Exploring basic concepts" (developerWorks, October 2006) examines some fundamental features of Business State Machines, and shows how you can use these concepts to implement the most basic vending machine.
-
"Implementing two-way interactions between a business state machine and a human task using WebSphere Process Server" (developerWorks, June 2006) discusses how to use business state machines and human tasks together, using an example that requires a human approval step for a simplified order process implemented as a business state machine.
-
"IBM WebSphere Developer Technical Journal: A guided tour of WebSphere Integration Developer -- Part 4" (developerWorks, June 2006) explores a service-oriented approach to application integration using IBM WebSphere Integration Developer.
-
Find the product documentation you need for Installing and starting Business Process Choreographer Explorer: IBM WebSphere Business Process Management Version 6.0 information center.
-
Get product information from the WebSphere Integration Developer product page.
-
Find the resources you need to advance your skills from the IBM WebSphere Business Process Management Version 6.0 information center.
-
Access the latest business process management and application connectivity resources on the WebSphere business integration zone.
-
Browse the technology bookstore for books on these and other technical topics.
Get products and technologies
- Build your
next development project with IBM trial software, available for download directly from
developerWorks.
Discuss
-
Check out Bobby Wolf's WebSphere SOA and J2EE in Practice blog. This blog discusses how to use SOA, J2EE, and related technologies to develop business applications, including how to make best use of IBM J2EE products like WebSphere Application Server and Rational Application Developer, and IBM SOA products like WebSphere Process Server and WebSphere Integration Developer.
Comments (Undergoing maintenance)






