Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Â
BPMS1
1. GeoBliki
Pat Cappelaere
pat@geobliki.com
Linda Derezinski
linda@geobliki.com
And GeoBPMS June 7th, 2007
Part I
Business Process Management System For the Enterprise Using Open Source
Components
Targeted Audience: Rails Integrators, Business Process Analysts and OpenWFEru
enthusiasts.
Warning: This is not a Ruby or Rails tutorial. This document assumes that you have a
working knowledge of Ruby and Rails.
BPMS Business Case:
Sophisticated products and/or automation require the definition of service chains (or
workflows) that can involve many participants from humans to web services collaborating in
a seamless manner. These processes need to be managed and defined at the Enterprise level
and fall in a category called: Business Process Management.
This can be fairly complex and expensive. Many acronyms and technologies need to be
mastered. Our goal is to show that we can put together a solid framework based around open
source components and keep it relatively simple and manageable. Letâs walk through an
example.
Scope of this document:
- Step description of all components and tools required for BPMS and integration within
Ruby on Rails.
- Example of a workflow with code snippets.
www.geobliki.com
2. Introduction:
Service-chains can be defined to sequence and allocate activities or tasks across many
participants using workflows.
First step is to capture and visualize the process. A good picture is worth a thousand words.
So we need to make it look really good!
There are many ways to generate Business Process diagrams. A de-facto notation standard
has been released in Feb 2006 (BPMN1) supported by more than 42 implementations (as of
April 12, 2007). Eclipse is actively working on its own STP BPMN Modeler2. For the time
being, we will be using Business Process Visual Architect3 from Visual Paradigm.
Preflight check-list:
Before getting into the tutorial, check to see that you have everything required.
1) You have Ruby and Rails4 installed. Check that you have at least the following
versions.
ï ruby âversion
ruby 1.8.6
ï rails âversion
Rails 1.2.3
If you need to install Ruby on Rails:
For Windows, use Instant Rails.
For Mac OS X, use Locomotive.
For Linux, try the Rails LiveCD.
A good development environment on Macintosh is TextMate5 or Eclipse with Ruby RDT6 on
all platforms.
To get rolling with Ruby on Rails: Check this out
2) MySQL7 installed. 4.x distribution or later is fine.
ï mysql âversion
mysql Ver 14.12 Distrib 5.0.20a
If you need to install MySQL download
1
http://www.bpmn.org/
2
http://www.eclipse.org/stp/bpmn/
3
http://www.visual-paradigm.com/product/bpva/
4
http://www.rubyonrails.org/
5
http://macromates.com/
6
http://www-128.ibm.com/developerworks/opensource/library/os-rubyeclipse/
7
http://www.mysql.org
www.geobliki.com
3. Create a empty Rails application âgeobpmsâ
ï rails geobpms
And make sure it works by testing it â Start the application
ï cd geobpms
ï ./script/server
in your favorite browser, go to http://127.0.0.1:3000/
Double check the environment one more time by selecting the âAbout your
applicationâs environmentâ link. You should have these or later versions:
www.geobliki.com
4. Download OpenWFERu
Go to: http://openwferu.rubyforge.org/
You can get it as a gem, latest stable version or from the svn trunk.
Note: My personal preference is to download the latest version and keep it under control so I
can go back to previous version as necessary (or check what changed between versions).
Install the gem
ï gem install -y openwferu
Successfully installed openwferu-0.9.11
Installing ri documentation for openwferu-0.9.11...
Installing RDoc documentation for openwferu-0.9.11...
Copy the gem into your vendor directory. In this case the current version is 0.9.11. From
your geobpms rails project directory
ï cp âR /usr/local/lib/ruby/gems/1.8/gems/openwferu-0.9.11 vendor/
Edit geobpms/config/environment.rb to point to the newly installed version of openwferu
Add this text:
config.load_paths += %W(
vendor/openwferu-0.9.11/lib
).map {|dir| "#{RAILS_ROOT}/#{dir}"}.select { |dir|
File.directory?(dir) }
Below the commented out config.load_paths line like so:
To change between versions, change the version number on line #25.
www.geobliki.com
5. Workflow Description:
This workflow example shows the tasking request of the EO-1 satellite by a user who interacts
with the system via XForms. The user enters a tasking request using some input (lat/longâŠ).
The workflow proceeds by calling the Sensor Planning System (SPS) to check for feasibilities.
The user is prompted to select a feasibility and the task is submitted. Eventually, the task is
completed onboard. The data is down-linked to the ground and published by the Sensor
Observation Service (SOS). Finally the user is alerted that data is available via email by the Web
Notification Service (WNS).
Figure 1. âSimpleâ EO1 Satellite Tasking Workflow
www.geobliki.com
6. The various participants in this workflows are: XForms, SPS, SOS and WNS. They are
represented as Pools. They perform various tasks for this workflow.
Ideally, we would save this workflow in OpenWFERu XML format (or XPDL 2.0 and then
translate it). This would be a possible outcome:
Create a workflows directory in the public folder and then copy the following into flow.xml.
/rails/public/workflows/flow.xml
<process-definition
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.openwfe.org/flowdef.xsd"
name="EO1 Simple Tasking Workflow"
revision="0.1"
theme="n/a"
security="restricted" >
<sequence>
<set field="msg" value="Workflow has been sequenced" />
<participant ref="WNS" task='Email' />
<participant ref='XForms' task='RequestTasking' comments='Enter EO-1 Tasking Parameters'
/>
<participant ref="SPS" task='GetFeasibilities' timeout="2d" comments='Check EO-1
Tasking Feasibilities'/>
<participant ref='XForms' task='SelectFeasibility' comments='Select Desired Feasibility'
/>
<cancel-process if="${f:status} == 'cancelled'" />
<participant ref="SPS" task='Submit' comments='Submit Task to JPL'/>
<cancel-process if="${f:status} == 'cancelled'" />
<participant ref="SOS" task='Publish' comments="SOS will make raw data file
available"/>
<set field="msg" value="You've got data" />
<participant ref="WNS" task='Email' />
</sequence>
</process-definition>
Implementation Details:
Step 1: Tell OpenWFERu about those participants
I created a small class to create the workflow engine and register the participants. Some of
the participants are in-lined as examples. Major participants have their own classes.
www.geobliki.com
7. /rails/lib/wfe.rb
require 'openwfe/engine/engine'
require 'openwfe/expool/history'
require 'openwfe/expool/journal'
require 'openwfe/engine/file_persisted_engine'
require 'rexml/document'
class Wfe
def self.create_wfe_engine_and_participants
#
# === the ENGINE itself as a global variable
#
$engine = OpenWFE::Engine.new
#
# dumps all the process history in a file name "history.log"
# in the work directory
$engine.init_service("history", FileHistory)
# -- process journaling
$engine.init_service("journal", Journal)
$engine.application_context[:keep_journals] = true
#
# === some LISTENERS
#
#
# === the PARTICIPANTS
#
$engine.register_participant :WPS do |workitem|
puts "wps output file:"+workitem.processed_file
end
$engine.register_participant("XForms", XformParticipant.new )
$engine.register_participant("SPS", SpsParticipant.new )
$engine.register_participant :WNS do | flowexpression, workitem|
# Check msg and email it
puts "WNS Task:"+workitem.params['task']
puts "msg:"+workitem.msg
end
$engine.register_participant :SOS do | flowexpression, workitem|
puts "SOS Task:"+workitem.params['task']
end
puts "workflow engine started..."
end
end
At the bottom of your environment file /rails/config/environment.rb, add these lines:
require "wfe"
Wfe.create_wfe_engine_and_participants
www.geobliki.com
8. Now we need to create our SPS participant. The Sensor Planning Service is a web service
that requires the posting of specific XML snippets to a URL. This service has many methods
and we will only use two of them:
- GetFeasibilities, to return the imaging feasibilities for a specific latitude/longitude.
- Submit, to package the requested parameters and request the tasking to happen.
The various tasks of this participant will pick up the required parameters in the workitem.
The user will have entered those parameters in previous steps (later for more information)
Letâs create two stubbed participants, to get our first workflow working
/rails/lib/sps_participant.rb
require 'openwfe/participants/participant'
class SpsParticipant
include LocalParticipant
def logger
@logger ||= RAILS_DEFAULT_LOGGER || Logger.new(STDOUT)
end
#
# Consume the workitem received from engine
#
def consume (workitem)
fe = get_flow_expression(workitem)
task = fe.attributes['task']
raise "request parameter is undefined" if task == nil
logger.debug("SPS Participant Request: #{task}")
reply_to_engine(workitem)
end
end
www.geobliki.com
9. and /rails/lib/xform_participant.rb
require 'openwfe/participants/participant'
class XformParticipant
include LocalParticipant
def logger
@logger ||= RAILS_DEFAULT_LOGGER || Logger.new(STDOUT)
end
#
# Consume the workitem received from engine
#
def consume (workitem)
fe = get_flow_expression(workitem)
task = fe.attributes['task']
raise "request parameter is undefined" if task == nil
logger.debug("XForm Participant Request: #{task}")
reply_to_engine(workitem)
end
end
How Do I execute a Workflow?
Somehow the user could discover what workflows are available, pick one from a list or a
database.
One could quickly create a rails controller and a launch method. Other methods can be
written to view, add, delete workflows to the listâŠ
Letâs create a rails controller âWorklistâ and 2 methods: intialize & launch. From the rails
project directory:
ï ./script/generate controller Worklist initialize launch
www.geobliki.com
10. Letâs edit the file generated in geobpms/app/controller/worklist_controller.rb.
We will complete the initialize and launch methods.
class WorklistController < ApplicationController
def initialize
@workflows_dir = "#{RAILS_ROOT}/public/workflows/"
end
def launch
workflow_name = params[:id]
#get the process flow from file based on passed-in parameter
flow = IO.read("#{@workflows_dir}#{workflow_name}.xml")
launchitem = LaunchItem.new(flow)
fei,t = $engine.launch(launchitem)
puts "launching fei: #{fei.to_s}"
puts "inspect:"+fei.inspect
@wfid = fei.wfid
end
end
Before running this, letâs quickly add a view to render the results
Rails has created for us:
/geobpms/app/views/worklist/launch.rhtml
<h1>Worklist#launch</h1>
<h2>Your workflow has been launched successfully!</h2>
<h3> Flow id: <%= @wfid %></h3>
Time to test it out to see what we have so far:
Start your application
ï ./script/server
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
workflow engine started...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready. TERM => stop. USR2 => restart. INT => stop (no
restart).
** Rails signals registered. HUP => reload (without restart). It
might not work well.
** Mongrel available at 0.0.0.0:3000
** Use CTRL-C to stop.
www.geobliki.com
11. and from your web browser, try this:
http://localhost:3000/worklist/launch/flow
You should see in your browser something like:
The terminal window should show something like:
launching fei: (fei 0.9.11 engine/engine field:__definition
EO1_Simple_Tasking_Workflow 0.1 20070606-koyobibute process-definition 0)
inspect:#<OpenWFE::FlowExpressionId:0x322cc7c
@workflow_definition_revision="0.1", @engine_id="engine",
@workflow_definition_name="EO1_Simple_Tasking_Workflow",
@expression_name="process-definition", @expression_id="0",
@initial_engine_id="engine", @workflow_instance_id="20070606-koyobibute",
@workflow_definition_url="field:__definition", @owfe_version="0.9.11">
WNS Task:Email
msg:Workflow has been sequenced
SOS Task:Publish
WNS Task:Email
msg:You've got data
Processing WorklistController#launch (for 127.0.0.1 at 2007-06-06
15:19:21) [GET]
Session ID: cebe910aa8bbad3201d752b6d5ddde4c
Parameters: {"action"=>"launch", "id"=>"flow", "controller"=>"worklist"}
script/../config/../public/workflows/flow.xml
Rendering worklist/launch
Completed in 0.01020 (98 reqs/sec) | Rendering: 0.00111 (10%) | 200 OK
[http://localhost/worklist/launch/flow]
XForm Participant Request: RequestTasking
SPS Participant Request: GetFeasibilities
XForm Participant Request: SelectFeasibility
SPS Participant Request: Submit
Congratulations, you have successfully run your first workflow within Rails!
In the tradition of Rails, we need to capture this milestone and create a test.
[We should have written the test first âŠ]
Note: If you havenât already stopped your application, do that now by pressing CTRL-C in
the terminal window.
www.geobliki.com
12. First lets get the databases setup. Edit your database configuration file:
geobpms/config/database.yml
Set the username and password for each of the databases to what ever you would like to use.
In MySQL create geobpms_development, geobpms_test, geobpms_production databases
with the username and password you put in database.yml.
Go to your application directory and type:
ï rake test
(in /Users/linda/work/geobpms)
workflow engine started...
/usr/local/bin/ruby -Ilib:test "/usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader.rb"
/usr/local/bin/ruby -Ilib:test "/usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader.rb"
"test/functional/worklist_controller_test.rb"
workflow engine started...
Loaded suite /usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader
Started
.
Finished in 0.038817 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
/usr/local/bin/ruby -Ilib:test "/usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader.rb" and it should pass.
Rails already created a test stub for your controller in:
geobpms/test/functional/worklist_controller_test.rb
Now we need to replace the test_truth method with something like:
def test_launch_flow
get :launch, :id=>"flow"
assert_template 'launch'
end
Exercise the test:
ï rake test
(in /Users/linda/work/geobpms)
workflow engine started...
/usr/local/bin/ruby -Ilib:test
"/usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader.rb"
/usr/local/bin/ruby -Ilib:test
"/usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader.rb"
"test/functional/worklist_controller_test.rb"
workflow engine started...
Loaded suite /usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader
Started
www.geobliki.com
13. launching fei: (fei 0.9.11 engine/engine field:__definition
EO1_Simple_Tasking_Workflow 0.1 20070606-kusokadami process-
definition 0)
inspect:#<OpenWFE::FlowExpressionId:0x3216490
@expression_name="process-definition",
@workflow_definition_url="field:__definition", @engine_id="engine",
@initial_engine_id="engine", @workflow_instance_id="20070606-
kusokadami", @owfe_version="0.9.11", @expression_id="0",
@workflow_definition_revision="0.1",
@workflow_definition_name="EO1_Simple_Tasking_Workflow">
.
Finished in 0.082942 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
/usr/local/bin/ruby -Ilib:test
"/usr/local/lib/ruby/gems/1.8/gems/rake-
0.7.3/lib/rake/rake_test_loader.rb"
Congratulations, you have successfully run your first workflow test within Rails!
TO BE CONTINUED.
www.geobliki.com