Skip to main content

WebSphere Process Server Business State Machines, Part 2: Enhancing your vending machine

James Carey (jecarey@us.ibm.com), Senior Software Engineer, IBM
James Carey is currently a senior software engineer with IBM's System & Technology Group. Previously James was a member of the WebSphere Process Server architecture team where he focused on Business State Machines.
Geoffrey Beers (gbeers@us.ibm.com), Software Engineer, IBM
Geoffrey Beers is a software engineer at IBM in Rochester, Minnesota. He works in the Bringup Lab and SWAT team for WebSphere Process Server.

Summary:  In the first article of this series, we discussed the differences between BPEL processes and Business State Machines, observing that state machines provide a good solution for "nouns" that are event driven and have looping. We created a basic vending machine and tested it using the BPC Explorer. This article further enables your BSM skills, so you can enhance the vending machine to collect money, introduce actions, and test using component test. In the final article, you will extend the vending machine by making it dispense products, introducing conditions and timeouts, and testing it using the debugger. You'll also look at simplifying the state machine through the use of composite states.

View more content in this series

Date:  21 Feb 2007
Level:  Intermediate
Activity:  421 views

Introduction

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.


Powering on and off

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
Figure 1. The simple vending machine with power on and power off

Collecting money

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
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
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
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 serialNumber of 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 totalDeposited variable.
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
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
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
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
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
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
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
Figure 11. Deposit money in the vending machine

The result is that in the Events window:


Figure 12. Results in component test after deposit
Figure 12. Results in component test after deposit

And in the console we see:


Figure 13. Results in snippet logs after deposit
Figure 13. Results in snippet logs after deposit

We can also call getState from component test:


Figure 14. Calling getState in 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
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
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.


Summary

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.


Resources

Learn

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.

About the authors

James Carey is currently a senior software engineer with IBM's System & Technology Group. Previously James was a member of the WebSphere Process Server architecture team where he focused on Business State Machines.

Geoffrey Beers

Geoffrey Beers is a software engineer at IBM in Rochester, Minnesota. He works in the Bringup Lab and SWAT team for WebSphere Process Server.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=197063
ArticleTitle=WebSphere Process Server Business State Machines, Part 2: Enhancing your vending machine
publish-date=02212007
author1-email=jecarey@us.ibm.com
author1-email-cc=
author2-email=gbeers@us.ibm.com
author2-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers