ruote 0.9.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +24 -0
- data/bin/validate-workflow.rb +89 -0
- data/examples/about_state.rb +81 -0
- data/examples/bigflow.rb +19 -0
- data/examples/csv_weather.rb +23 -0
- data/examples/engine_template.rb +247 -0
- data/examples/flowtracing.rb +24 -0
- data/examples/homeworkreview.rb +68 -0
- data/examples/kotoba.rb +22 -0
- data/examples/mano_tracker.rb +172 -0
- data/examples/openwferu.rb +58 -0
- data/examples/quotereporter.rb +157 -0
- data/examples/scheduler_cron_usage.rb +48 -0
- data/examples/scheduler_usage.rb +56 -0
- data/lib/openwfe.rb +41 -0
- data/lib/openwfe/contextual.rb +111 -0
- data/lib/openwfe/def.rb +46 -0
- data/lib/openwfe/engine.rb +37 -0
- data/lib/openwfe/engine/engine.rb +756 -0
- data/lib/openwfe/engine/expool_methods.rb +172 -0
- data/lib/openwfe/engine/file_persisted_engine.rb +105 -0
- data/lib/openwfe/engine/participant_methods.rb +133 -0
- data/lib/openwfe/engine/status_methods.rb +353 -0
- data/lib/openwfe/engine/update_exp_methods.rb +112 -0
- data/lib/openwfe/exceptions.rb +51 -0
- data/lib/openwfe/expool/errorjournal.rb +476 -0
- data/lib/openwfe/expool/expressionpool.rb +1144 -0
- data/lib/openwfe/expool/expstorage.rb +403 -0
- data/lib/openwfe/expool/history.rb +174 -0
- data/lib/openwfe/expool/journal.rb +224 -0
- data/lib/openwfe/expool/journal_replay.rb +321 -0
- data/lib/openwfe/expool/parser.rb +242 -0
- data/lib/openwfe/expool/representation.rb +121 -0
- data/lib/openwfe/expool/threadedexpstorage.rb +188 -0
- data/lib/openwfe/expool/wfidgen.rb +388 -0
- data/lib/openwfe/expool/yamlexpstorage.rb +224 -0
- data/lib/openwfe/expressions/condition.rb +244 -0
- data/lib/openwfe/expressions/environment.rb +246 -0
- data/lib/openwfe/expressions/expressionmap.rb +258 -0
- data/lib/openwfe/expressions/fe_cancel.rb +109 -0
- data/lib/openwfe/expressions/fe_command.rb +241 -0
- data/lib/openwfe/expressions/fe_concurrence.rb +662 -0
- data/lib/openwfe/expressions/fe_cron.rb +259 -0
- data/lib/openwfe/expressions/fe_cursor.rb +259 -0
- data/lib/openwfe/expressions/fe_define.rb +192 -0
- data/lib/openwfe/expressions/fe_do.rb +168 -0
- data/lib/openwfe/expressions/fe_equals.rb +291 -0
- data/lib/openwfe/expressions/fe_filter.rb +129 -0
- data/lib/openwfe/expressions/fe_filter_definition.rb +168 -0
- data/lib/openwfe/expressions/fe_fqv.rb +250 -0
- data/lib/openwfe/expressions/fe_if.rb +303 -0
- data/lib/openwfe/expressions/fe_iterator.rb +145 -0
- data/lib/openwfe/expressions/fe_listen.rb +371 -0
- data/lib/openwfe/expressions/fe_losfor.rb +111 -0
- data/lib/openwfe/expressions/fe_misc.rb +421 -0
- data/lib/openwfe/expressions/fe_participant.rb +269 -0
- data/lib/openwfe/expressions/fe_reserve.rb +212 -0
- data/lib/openwfe/expressions/fe_save.rb +274 -0
- data/lib/openwfe/expressions/fe_sequence.rb +117 -0
- data/lib/openwfe/expressions/fe_set.rb +139 -0
- data/lib/openwfe/expressions/fe_sleep.rb +166 -0
- data/lib/openwfe/expressions/fe_step.rb +159 -0
- data/lib/openwfe/expressions/fe_subprocess.rb +168 -0
- data/lib/openwfe/expressions/fe_timeout.rb +127 -0
- data/lib/openwfe/expressions/fe_wait.rb +78 -0
- data/lib/openwfe/expressions/fe_when.rb +142 -0
- data/lib/openwfe/expressions/filter.rb +104 -0
- data/lib/openwfe/expressions/flowexpression.rb +847 -0
- data/lib/openwfe/expressions/iterator.rb +221 -0
- data/lib/openwfe/expressions/merge.rb +84 -0
- data/lib/openwfe/expressions/raw.rb +547 -0
- data/lib/openwfe/expressions/rprocdef.rb +375 -0
- data/lib/openwfe/expressions/time.rb +333 -0
- data/lib/openwfe/expressions/timeout.rb +178 -0
- data/lib/openwfe/expressions/value.rb +126 -0
- data/lib/openwfe/filterdef.rb +259 -0
- data/lib/openwfe/flowexpressionid.rb +357 -0
- data/lib/openwfe/listeners/listener.rb +97 -0
- data/lib/openwfe/listeners/listeners.rb +139 -0
- data/lib/openwfe/listeners/socketlisteners.rb +272 -0
- data/lib/openwfe/logging.rb +122 -0
- data/lib/openwfe/omixins.rb +95 -0
- data/lib/openwfe/orest/controlclient.rb +119 -0
- data/lib/openwfe/orest/definitions.rb +113 -0
- data/lib/openwfe/orest/exception.rb +60 -0
- data/lib/openwfe/orest/oldrestservlet.rb +279 -0
- data/lib/openwfe/orest/osocket.rb +148 -0
- data/lib/openwfe/orest/restclient.rb +176 -0
- data/lib/openwfe/orest/workitem.rb +206 -0
- data/lib/openwfe/orest/worklistclient.rb +272 -0
- data/lib/openwfe/orest/xmlcodec.rb +670 -0
- data/lib/openwfe/participants.rb +38 -0
- data/lib/openwfe/participants/enoparticipants.rb +230 -0
- data/lib/openwfe/participants/participant.rb +141 -0
- data/lib/openwfe/participants/participantmap.rb +249 -0
- data/lib/openwfe/participants/participants.rb +407 -0
- data/lib/openwfe/participants/soapparticipants.rb +135 -0
- data/lib/openwfe/participants/socketparticipants.rb +202 -0
- data/lib/openwfe/participants/storeparticipants.rb +254 -0
- data/lib/openwfe/rudefinitions.rb +130 -0
- data/lib/openwfe/service.rb +103 -0
- data/lib/openwfe/storage/yamlcustom.rb +106 -0
- data/lib/openwfe/storage/yamlfilestorage.rb +245 -0
- data/lib/openwfe/tools/flowtracer.rb +81 -0
- data/lib/openwfe/util/dollar.rb +217 -0
- data/lib/openwfe/util/irb.rb +86 -0
- data/lib/openwfe/util/observable.rb +144 -0
- data/lib/openwfe/util/ometa.rb +62 -0
- data/lib/openwfe/util/workqueue.rb +124 -0
- data/lib/openwfe/util/xml.rb +418 -0
- data/lib/openwfe/utils.rb +554 -0
- data/lib/openwfe/version.rb +37 -0
- data/lib/openwfe/workitem.rb +499 -0
- data/lib/openwfe/worklist/oldrest.rb +244 -0
- data/lib/openwfe/worklist/storelocks.rb +293 -0
- data/lib/openwfe/worklist/storeparticipant.rb +44 -0
- data/lib/openwfe/worklist/worklist.rb +297 -0
- data/test/README.txt +27 -0
- data/test/back_0916_test.rb +111 -0
- data/test/bm/bm_1_xml_vs_prog.rb +56 -0
- data/test/bm/bm_2_step.rb +109 -0
- data/test/bm/ft_0f_5ms.rb +35 -0
- data/test/bm/ft_26_load.rb +210 -0
- data/test/bm/ft_26b_load.rb +86 -0
- data/test/bm/ft_26c_load.rb +97 -0
- data/test/bm/ft_26d_load.rb +97 -0
- data/test/bm/ft_recu.rb +71 -0
- data/test/clone_test.rb +122 -0
- data/test/concurrence_test.rb +77 -0
- data/test/condition_test.rb +155 -0
- data/test/console_test.rb +12 -0
- data/test/cron_ltest.rb +15 -0
- data/test/description_test.rb +87 -0
- data/test/eno_test.rb +76 -0
- data/test/expmap_test.rb +54 -0
- data/test/expool_20031219_0916.tgz +0 -0
- data/test/fe_lookup_att_test.rb +62 -0
- data/test/fei_test.rb +181 -0
- data/test/file_persisted_engine_test.rb +64 -0
- data/test/file_persistence_test.rb +134 -0
- data/test/filep_cancel_test.rb +123 -0
- data/test/filter_test.rb +109 -0
- data/test/flowtestbase.rb +351 -0
- data/test/ft_0.rb +68 -0
- data/test/ft_0b_sequence.rb +36 -0
- data/test/ft_0c_testname.rb +33 -0
- data/test/ft_0d_participant.rb +30 -0
- data/test/ft_0e_multibody.rb +34 -0
- data/test/ft_10_loop.rb +134 -0
- data/test/ft_11_ppd.rb +415 -0
- data/test/ft_11b_ppd.rb +54 -0
- data/test/ft_12_blockparticipant.rb +97 -0
- data/test/ft_13_eno.rb +52 -0
- data/test/ft_14_subprocess.rb +88 -0
- data/test/ft_14b_subprocess.rb +192 -0
- data/test/ft_14c_subprocess.rb +68 -0
- data/test/ft_15_iterator.rb +216 -0
- data/test/ft_15b_iterator.rb +74 -0
- data/test/ft_16_fqv.rb +73 -0
- data/test/ft_17_condition.rb +84 -0
- data/test/ft_18_pname.rb +56 -0
- data/test/ft_1_unset.rb +175 -0
- data/test/ft_1b_unset.rb +39 -0
- data/test/ft_20_cron.rb +53 -0
- data/test/ft_21_cron.rb +87 -0
- data/test/ft_21b_cron_pause.rb +82 -0
- data/test/ft_22_history.rb +74 -0
- data/test/ft_23_when.rb +77 -0
- data/test/ft_23b_when.rb +70 -0
- data/test/ft_23c_wait.rb +80 -0
- data/test/ft_23d_cww.rb +58 -0
- data/test/ft_24_def.rb +44 -0
- data/test/ft_25_cancel.rb +89 -0
- data/test/ft_27_getflowpos.rb +147 -0
- data/test/ft_28_fileparticipant.rb +63 -0
- data/test/ft_29_httprb.rb +106 -0
- data/test/ft_2_concurrence.rb +135 -0
- data/test/ft_2b_concurrence.rb +188 -0
- data/test/ft_2c_concurrence.rb +64 -0
- data/test/ft_30_socketlistener.rb +203 -0
- data/test/ft_31_flowname.rb +40 -0
- data/test/ft_32_journal.rb +91 -0
- data/test/ft_32c_journal.rb +102 -0
- data/test/ft_32d_journal.rb +84 -0
- data/test/ft_33_description.rb +107 -0
- data/test/ft_34_cancelwfid.rb +80 -0
- data/test/ft_35_localdefs.rb +75 -0
- data/test/ft_36_subprocids.rb +97 -0
- data/test/ft_37_pnames.rb +70 -0
- data/test/ft_38_tag.rb +127 -0
- data/test/ft_38b_tag.rb +161 -0
- data/test/ft_38c_tag.rb +100 -0
- data/test/ft_39_reserve.rb +63 -0
- data/test/ft_39b_reserve.rb +84 -0
- data/test/ft_3_equals.rb +170 -0
- data/test/ft_3b_lookup_vf.rb +83 -0
- data/test/ft_40_defined.rb +61 -0
- data/test/ft_41_case.rb +110 -0
- data/test/ft_42_environments.rb +75 -0
- data/test/ft_43_pat10.rb +85 -0
- data/test/ft_44_save.rb +70 -0
- data/test/ft_44b_restore.rb +212 -0
- data/test/ft_45_citerator.rb +214 -0
- data/test/ft_46_pparams.rb +62 -0
- data/test/ft_47_filter.rb +160 -0
- data/test/ft_48_fe_filter.rb +88 -0
- data/test/ft_49_condition.rb +126 -0
- data/test/ft_4_misc.rb +237 -0
- data/test/ft_50_xml_attribute.rb +155 -0
- data/test/ft_51_stack.rb +55 -0
- data/test/ft_52_obs_participant.rb +123 -0
- data/test/ft_53_null_noop_participant.rb +62 -0
- data/test/ft_54_listen.rb +288 -0
- data/test/ft_54b_listen.rb +66 -0
- data/test/ft_54c_listen.rb +99 -0
- data/test/ft_55_ptimeout.rb +59 -0
- data/test/ft_56_timeout.rb +59 -0
- data/test/ft_57_a.rb +145 -0
- data/test/ft_58_ejournal.rb +151 -0
- data/test/ft_59_ps.rb +150 -0
- data/test/ft_59b_ps_for_pat.rb +58 -0
- data/test/ft_5_time.rb +118 -0
- data/test/ft_60_ecancel.rb +161 -0
- data/test/ft_61_elsub.rb +51 -0
- data/test/ft_62_procparticipant.rb +71 -0
- data/test/ft_63_pause.rb +124 -0
- data/test/ft_64_alias.rb +102 -0
- data/test/ft_64_clone.rb +69 -0
- data/test/ft_65_stringlaunch.rb +59 -0
- data/test/ft_66_subforget.rb +70 -0
- data/test/ft_67_schedlaunch.rb +116 -0
- data/test/ft_68_ifparticipant.rb +70 -0
- data/test/ft_69_cancelmissing.rb +51 -0
- data/test/ft_6_lambda.rb +64 -0
- data/test/ft_70_lookupvar.rb +55 -0
- data/test/ft_71_log.rb +60 -0
- data/test/ft_72_lookup_processes.rb +76 -0
- data/test/ft_73_cancel_sub.rb +139 -0
- data/test/ft_74_block_and_workitem_dup.rb +63 -0
- data/test/ft_75_ruby_attributes.rb +87 -0
- data/test/ft_76_merge_isolate.rb +88 -0
- data/test/ft_77_segments.rb +35 -0
- data/test/ft_78_eval.rb +150 -0
- data/test/ft_79_tticket.rb +187 -0
- data/test/ft_79b_tticket.rb +172 -0
- data/test/ft_79c_outcome.rb +56 -0
- data/test/ft_7_lose.rb +104 -0
- data/test/ft_7b_lose.rb +78 -0
- data/test/ft_80_spname.rb +91 -0
- data/test/ft_81_exp.rb +60 -0
- data/test/ft_82_trecu.rb +46 -0
- data/test/ft_83_badpause.rb +58 -0
- data/test/ft_84_updateexp.rb +198 -0
- data/test/ft_85_dolhash.rb +43 -0
- data/test/ft_86_dollar_fv.rb +68 -0
- data/test/ft_87_define.rb +74 -0
- data/test/ft_8_forget.rb +44 -0
- data/test/ft_9_cursor.rb +145 -0
- data/test/ft_9b_cursor.rb +105 -0
- data/test/ft_tests.rb +124 -0
- data/test/hash_test.rb +75 -0
- data/test/hparticipant_test.rb +164 -0
- data/test/lookup_att_test.rb +90 -0
- data/test/lookup_vf_test.rb +94 -0
- data/test/misc_test.rb +90 -0
- data/test/nut_0_irb.rb +20 -0
- data/test/obs_test.rb +142 -0
- data/test/orest_test.rb +251 -0
- data/test/param_test.rb +290 -0
- data/test/participant_test.rb +101 -0
- data/test/pending.rb +23 -0
- data/test/ps_representation.rb +133 -0
- data/test/rake_ltest.rb +38 -0
- data/test/rake_qtest.rb +68 -0
- data/test/raw_prog_test.rb +412 -0
- data/test/restart_cron_test.rb +136 -0
- data/test/restart_paused_test.rb +98 -0
- data/test/restart_sleep_test.rb +140 -0
- data/test/restart_tests.rb +18 -0
- data/test/restart_when_test.rb +112 -0
- data/test/ruby_procdef_test.rb +132 -0
- data/test/rutest_utils.rb +63 -0
- data/test/sec_test.rb +205 -0
- data/test/slock_test.rb +80 -0
- data/test/storage_test.rb +44 -0
- data/test/test.rb +3 -0
- data/test/timeout_test.rb +105 -0
- data/test/util_xml_test.rb +112 -0
- data/test/wfid_test.rb +175 -0
- data/test/wi_test.rb +75 -0
- metadata +433 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
# list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
|
17
|
+
# used to endorse or promote products derived from this software without
|
|
18
|
+
# specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#++
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# "made in Japan"
|
|
36
|
+
#
|
|
37
|
+
# John Mettraux at openwfe.org
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
require 'yaml'
|
|
41
|
+
|
|
42
|
+
require 'openwfe/utils'
|
|
43
|
+
require 'openwfe/util/dollar'
|
|
44
|
+
require 'openwfe/participants/participant'
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# some base participant implementations
|
|
49
|
+
#
|
|
50
|
+
module OpenWFE
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# Just dumps the incoming workitem in a file as a YAML String.
|
|
54
|
+
#
|
|
55
|
+
# By default, this participant will not reply to the engine once
|
|
56
|
+
# the workitem got dumped to its file, but you can set its
|
|
57
|
+
# reply_anyway field to true to make it reply anyway...
|
|
58
|
+
#
|
|
59
|
+
class FileParticipant
|
|
60
|
+
include LocalParticipant
|
|
61
|
+
|
|
62
|
+
attr_accessor :reply_anyway, :workdir
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# The constructor expects as a unique optional param either the
|
|
66
|
+
# application_context either the 'output' dir for the participant.
|
|
67
|
+
#
|
|
68
|
+
def initialize (context_or_dir=nil)
|
|
69
|
+
|
|
70
|
+
@workdir = get_work_directory(context_or_dir) + "/out/"
|
|
71
|
+
|
|
72
|
+
@reply_anyway = false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# The method called by the engine for each incoming workitem.
|
|
77
|
+
#
|
|
78
|
+
def consume (workitem)
|
|
79
|
+
|
|
80
|
+
FileUtils.makedirs(@workdir) unless File.exist?(@workdir)
|
|
81
|
+
|
|
82
|
+
file_name = @workdir + determine_file_name(workitem)
|
|
83
|
+
|
|
84
|
+
dump_to_file(file_name, workitem)
|
|
85
|
+
|
|
86
|
+
reply_to_engine(workitem) if @reply_anyway
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
#
|
|
90
|
+
# This method does the actual job of dumping the workitem (as some
|
|
91
|
+
# YAML to a file).
|
|
92
|
+
# It can be easily overriden.
|
|
93
|
+
#
|
|
94
|
+
def dump_to_file (file_name, workitem)
|
|
95
|
+
|
|
96
|
+
File.open(file_name, "w") do |file|
|
|
97
|
+
file.print encode_workitem(workitem)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
#
|
|
102
|
+
# You can override this method to control into which file (name)
|
|
103
|
+
# each workitem gets dumped.
|
|
104
|
+
# You could even have a unique file for all workitems transiting
|
|
105
|
+
# through this participant.
|
|
106
|
+
#
|
|
107
|
+
def determine_file_name (workitem)
|
|
108
|
+
|
|
109
|
+
fei = workitem.fei
|
|
110
|
+
|
|
111
|
+
OpenWFE::ensure_for_filename(
|
|
112
|
+
"#{fei.wfid}_#{fei.expression_id}__" +
|
|
113
|
+
"#{fei.workflow_definition_name}__" +
|
|
114
|
+
"#{fei.workflow_definition_revision}" +
|
|
115
|
+
"#{workitem.participant_name}.yaml")
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
protected
|
|
119
|
+
|
|
120
|
+
#
|
|
121
|
+
# By default, uses YAML to serialize the workitem
|
|
122
|
+
# (of course you can override this method).
|
|
123
|
+
#
|
|
124
|
+
def encode_workitem (wi)
|
|
125
|
+
YAML.dump(wi)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# This participant is used by the register_participant() method of
|
|
131
|
+
# Engine class.
|
|
132
|
+
#
|
|
133
|
+
# engine.register_participant("the_boss") do |workitem|
|
|
134
|
+
# puts "the boss received a workitem"
|
|
135
|
+
# end
|
|
136
|
+
#
|
|
137
|
+
# After the block executes, the BlockParticipant immediately replies
|
|
138
|
+
# to the engine.
|
|
139
|
+
#
|
|
140
|
+
# You can pass a block with two arguments : flow_expression and workitem
|
|
141
|
+
# to BlockParticipant, it will automatically adapt.
|
|
142
|
+
#
|
|
143
|
+
# engine.register_participant("the_boss") do |fexp, wi|
|
|
144
|
+
# puts "the boss received a workitem from exp #{fexp.fei.to_s}"
|
|
145
|
+
# end
|
|
146
|
+
#
|
|
147
|
+
# Having the FlowExpression instance at hand allows for advanced tricks,
|
|
148
|
+
# beware...
|
|
149
|
+
#
|
|
150
|
+
# It's also OK to register a block participant without params :
|
|
151
|
+
#
|
|
152
|
+
# engine.register_participant :alice do
|
|
153
|
+
# puts "Alice received a workitem"
|
|
154
|
+
# end
|
|
155
|
+
#
|
|
156
|
+
class BlockParticipant
|
|
157
|
+
include LocalParticipant
|
|
158
|
+
|
|
159
|
+
def initialize (block0=nil, &block1)
|
|
160
|
+
@block = if block1
|
|
161
|
+
block1
|
|
162
|
+
else
|
|
163
|
+
block0
|
|
164
|
+
end
|
|
165
|
+
raise "Missing a block parameter" \
|
|
166
|
+
unless @block
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def consume (workitem)
|
|
170
|
+
|
|
171
|
+
result = call_block @block, workitem
|
|
172
|
+
|
|
173
|
+
workitem.set_result(result) \
|
|
174
|
+
if result and result != workitem
|
|
175
|
+
|
|
176
|
+
reply_to_engine(workitem) \
|
|
177
|
+
if workitem.kind_of? InFlowWorkItem
|
|
178
|
+
# else it's a cancel ite
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
#
|
|
183
|
+
# Simply aliasing a participant.
|
|
184
|
+
#
|
|
185
|
+
# engine.register_participant "toto" do |workitem|
|
|
186
|
+
# workitem.toto_message = "toto was here"
|
|
187
|
+
# end
|
|
188
|
+
# engine.register_participant "user_.*", AliasParticipant.new("toto")
|
|
189
|
+
#
|
|
190
|
+
# Workitems for participant whose name starts with 'user_' will be handled
|
|
191
|
+
# by participant 'toto'.
|
|
192
|
+
# Note that you can't use use a regex as the aliased name ("toto" in the
|
|
193
|
+
# example).
|
|
194
|
+
#
|
|
195
|
+
class AliasParticipant
|
|
196
|
+
include LocalParticipant
|
|
197
|
+
|
|
198
|
+
attr_reader :aliased_name
|
|
199
|
+
|
|
200
|
+
def initialize (aliased_name)
|
|
201
|
+
|
|
202
|
+
@aliased_name = aliased_name
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def consume (workitem)
|
|
206
|
+
|
|
207
|
+
get_participant_map.dispatch(nil, @aliased_name, workitem)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
#
|
|
212
|
+
# The NullParticipant never replies, it simply discards the workitems
|
|
213
|
+
# it receives.
|
|
214
|
+
#
|
|
215
|
+
class NullParticipant
|
|
216
|
+
include LocalParticipant
|
|
217
|
+
|
|
218
|
+
#
|
|
219
|
+
# Simply discards the incoming workitem
|
|
220
|
+
#
|
|
221
|
+
def consume (workitem)
|
|
222
|
+
# does nothing and does not reply to the engine.
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
#
|
|
227
|
+
# The NoOperationParticipant immediately replies to the engine upon
|
|
228
|
+
# receiving a workitem.
|
|
229
|
+
#
|
|
230
|
+
# Is used in testing. Could also be useful during the 'development'
|
|
231
|
+
# phase of a business process, as an empty placeholder.
|
|
232
|
+
#
|
|
233
|
+
class NoOperationParticipant
|
|
234
|
+
include LocalParticipant
|
|
235
|
+
|
|
236
|
+
#
|
|
237
|
+
# Simply discards the incoming workitem
|
|
238
|
+
#
|
|
239
|
+
def consume (workitem)
|
|
240
|
+
|
|
241
|
+
reply_to_engine workitem
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# The PrintParticipant will just emit its name to the
|
|
247
|
+
# test tracer if any or to the stdout else.
|
|
248
|
+
# Used by some unit tests.
|
|
249
|
+
#
|
|
250
|
+
class PrintParticipant
|
|
251
|
+
include LocalParticipant
|
|
252
|
+
|
|
253
|
+
def consume (workitem)
|
|
254
|
+
|
|
255
|
+
tracer = @application_context['__tracer']
|
|
256
|
+
|
|
257
|
+
if tracer
|
|
258
|
+
tracer << workitem.participant_name
|
|
259
|
+
tracer << "\n"
|
|
260
|
+
else
|
|
261
|
+
puts workitem.participant_name
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
reply_to_engine(workitem)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
#
|
|
269
|
+
# Links a process under a participant [name].
|
|
270
|
+
#
|
|
271
|
+
# Turns top level processes into participants
|
|
272
|
+
#
|
|
273
|
+
# Some examples :
|
|
274
|
+
#
|
|
275
|
+
# require 'engine/participants/participants'
|
|
276
|
+
#
|
|
277
|
+
# engine.register_participant(
|
|
278
|
+
# "transmit_to_accounting",
|
|
279
|
+
# "http://company.process.server.ie/processes/acc0.xml")
|
|
280
|
+
#
|
|
281
|
+
# engine.register_participant(
|
|
282
|
+
# "hr_resume_review_process",
|
|
283
|
+
# "file:/var/processes/hr_resume_review_process.rb")
|
|
284
|
+
#
|
|
285
|
+
# Some more examples :
|
|
286
|
+
#
|
|
287
|
+
# class RegistrationProcess < OpenWFE::ProcessDefinition
|
|
288
|
+
# sequence do
|
|
289
|
+
# participant :ref => "Alice"
|
|
290
|
+
# participant :ref => "Bob"
|
|
291
|
+
# end
|
|
292
|
+
# end
|
|
293
|
+
#
|
|
294
|
+
# # later in the code ...
|
|
295
|
+
#
|
|
296
|
+
# engine.register_participant("registration", RegistrationProcess)
|
|
297
|
+
#
|
|
298
|
+
# Or directly with some XML string :
|
|
299
|
+
#
|
|
300
|
+
# engine.register_participant("registration", '''
|
|
301
|
+
# <process-definition name="registration" revision="0.1">
|
|
302
|
+
# <sequence>
|
|
303
|
+
# <participant ref="Alice" />
|
|
304
|
+
# <participant ref="Bob" />
|
|
305
|
+
# </sequence>
|
|
306
|
+
# </process-definition>
|
|
307
|
+
# '''.strip)
|
|
308
|
+
#
|
|
309
|
+
# It's then easy to call the subprocess as if it were a participant :
|
|
310
|
+
#
|
|
311
|
+
# sequence do
|
|
312
|
+
# participant :ref => "registration"
|
|
313
|
+
# # or
|
|
314
|
+
# participant "registration"
|
|
315
|
+
# # or simply
|
|
316
|
+
# registration
|
|
317
|
+
# end
|
|
318
|
+
#
|
|
319
|
+
# Note that the 'subprocess' expression may be used as well :
|
|
320
|
+
#
|
|
321
|
+
# sequence do
|
|
322
|
+
# subprocess ref => "http://dms.company.org/processes/proc1.rb"
|
|
323
|
+
# end
|
|
324
|
+
#
|
|
325
|
+
# But you can't use the URL as an expression name for writing nice,
|
|
326
|
+
# concise, process definitions.
|
|
327
|
+
#
|
|
328
|
+
class ProcessParticipant
|
|
329
|
+
include LocalParticipant
|
|
330
|
+
|
|
331
|
+
#
|
|
332
|
+
# The 'object' may be the URL of a process definition or the process
|
|
333
|
+
# definition itself as an XML string or a Ruby process definition
|
|
334
|
+
# (as a class or in a String).
|
|
335
|
+
#
|
|
336
|
+
def initialize (object)
|
|
337
|
+
|
|
338
|
+
super()
|
|
339
|
+
|
|
340
|
+
template_uri = OpenWFE::parse_known_uri object
|
|
341
|
+
|
|
342
|
+
@template = template_uri || object
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
#
|
|
346
|
+
# This is the method called by the engine when it has a workitem
|
|
347
|
+
# for this participant.
|
|
348
|
+
#
|
|
349
|
+
def consume (workitem)
|
|
350
|
+
|
|
351
|
+
#get_expression_pool.launch_template(
|
|
352
|
+
# get_flow_expression(workitem),
|
|
353
|
+
# nil, # new environment
|
|
354
|
+
# 0, # sub_id
|
|
355
|
+
# @template,
|
|
356
|
+
# workitem)
|
|
357
|
+
# #params)
|
|
358
|
+
get_expression_pool.launch_subprocess(
|
|
359
|
+
get_flow_expression(workitem),
|
|
360
|
+
@template,
|
|
361
|
+
false, # don't forget
|
|
362
|
+
workitem,
|
|
363
|
+
nil) # no params for the new subprocess env
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
#
|
|
368
|
+
# This mixin provides an eval_template() method. This method assumes
|
|
369
|
+
# the target class has a @block_template and a @template, it also
|
|
370
|
+
# assumes the class includes the module LocalParticipant.
|
|
371
|
+
#
|
|
372
|
+
# This mixin is used for example in the MailParticipant class.
|
|
373
|
+
#
|
|
374
|
+
module TemplateMixin
|
|
375
|
+
|
|
376
|
+
#
|
|
377
|
+
# Given a workitem, expands the template and returns it as a String.
|
|
378
|
+
#
|
|
379
|
+
def eval_template (workitem)
|
|
380
|
+
|
|
381
|
+
fe = get_flow_expression workitem
|
|
382
|
+
|
|
383
|
+
template = if @block_template
|
|
384
|
+
|
|
385
|
+
call_block @block_template, workitem
|
|
386
|
+
|
|
387
|
+
elsif @template
|
|
388
|
+
|
|
389
|
+
template = if @template.kind_of?(File)
|
|
390
|
+
@template.readlines
|
|
391
|
+
else
|
|
392
|
+
@template.to_s
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
else
|
|
396
|
+
|
|
397
|
+
nil
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
return "(no template given)" unless template
|
|
401
|
+
|
|
402
|
+
OpenWFE::dosub template, fe, workitem
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
end
|
|
407
|
+
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
# list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
|
17
|
+
# used to endorse or promote products derived from this software without
|
|
18
|
+
# specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#++
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# "made in Japan"
|
|
36
|
+
#
|
|
37
|
+
# John Mettraux at openwfe.org
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
require 'soap/rpc/driver'
|
|
41
|
+
|
|
42
|
+
require 'openwfe/participants/participant'
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
module OpenWFE
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Wrapping a simple web service call within an OpenWFEru participant.
|
|
49
|
+
#
|
|
50
|
+
# quote_service = OpenWFE::SoapParticipant.new(
|
|
51
|
+
# "http://services.xmethods.net/soap", # service URI
|
|
52
|
+
# "urn:xmethods-delayed-quotes", # namespace
|
|
53
|
+
# "getQuote", # operation name
|
|
54
|
+
# [ "symbol" ]) # param arrays (workitem fields)
|
|
55
|
+
#
|
|
56
|
+
# engine.register_participant("quote_service", quote_service)
|
|
57
|
+
#
|
|
58
|
+
# By default, call params for the SOAP operations are determined by
|
|
59
|
+
# iterating the parameters and fetching the values under the
|
|
60
|
+
# corresponding workitem fields.
|
|
61
|
+
# This behaviour can be changed by overriding the prepare_call_params()
|
|
62
|
+
# method.
|
|
63
|
+
#
|
|
64
|
+
# On the return side, you can override the method handle_call_result
|
|
65
|
+
# for better mappings between web service calls and the workitems.
|
|
66
|
+
#
|
|
67
|
+
class SoapParticipant
|
|
68
|
+
include LocalParticipant
|
|
69
|
+
|
|
70
|
+
def initialize \
|
|
71
|
+
(endpoint_url, namespace, method_name, params, param_prefix="")
|
|
72
|
+
|
|
73
|
+
super()
|
|
74
|
+
|
|
75
|
+
@driver = SOAP::RPC::Driver.new(endpoint_url, namespace)
|
|
76
|
+
|
|
77
|
+
@method_name = method_name
|
|
78
|
+
@params = params
|
|
79
|
+
@param_prefix = param_prefix
|
|
80
|
+
|
|
81
|
+
@driver.add_method(method_name, *params)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# The method called by the engine when the flow reaches an instance
|
|
86
|
+
# of this Participant class.
|
|
87
|
+
#
|
|
88
|
+
def consume (workitem)
|
|
89
|
+
|
|
90
|
+
call_params = prepare_call_params(workitem)
|
|
91
|
+
|
|
92
|
+
call_result = @driver.send(@method_name, *call_params)
|
|
93
|
+
|
|
94
|
+
handle_call_result(call_result, workitem)
|
|
95
|
+
|
|
96
|
+
reply_to_engine(workitem)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# The base implementation : assumes that for each webservice operation
|
|
101
|
+
# param there is a workitem field with the same name.
|
|
102
|
+
#
|
|
103
|
+
# Feel free to override this method.
|
|
104
|
+
#
|
|
105
|
+
def prepare_call_params (workitem)
|
|
106
|
+
|
|
107
|
+
@params.collect do |param|
|
|
108
|
+
get_param workitem, param
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
#
|
|
113
|
+
# This implementation simply stuffs the result into the workitem
|
|
114
|
+
# as an attribute named "__result__".
|
|
115
|
+
#
|
|
116
|
+
# Feel free to override this method.
|
|
117
|
+
#
|
|
118
|
+
def handle_call_result (result, workitem)
|
|
119
|
+
|
|
120
|
+
workitem.attributes["__result__"] = result
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
protected
|
|
124
|
+
|
|
125
|
+
def get_param (workitem, param_name)
|
|
126
|
+
|
|
127
|
+
param_name = @param_prefix + param_name if @param_prefix
|
|
128
|
+
|
|
129
|
+
workitem.attributes[param_name] || ""
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
|