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.
Files changed (291) hide show
  1. data/README.txt +24 -0
  2. data/bin/validate-workflow.rb +89 -0
  3. data/examples/about_state.rb +81 -0
  4. data/examples/bigflow.rb +19 -0
  5. data/examples/csv_weather.rb +23 -0
  6. data/examples/engine_template.rb +247 -0
  7. data/examples/flowtracing.rb +24 -0
  8. data/examples/homeworkreview.rb +68 -0
  9. data/examples/kotoba.rb +22 -0
  10. data/examples/mano_tracker.rb +172 -0
  11. data/examples/openwferu.rb +58 -0
  12. data/examples/quotereporter.rb +157 -0
  13. data/examples/scheduler_cron_usage.rb +48 -0
  14. data/examples/scheduler_usage.rb +56 -0
  15. data/lib/openwfe.rb +41 -0
  16. data/lib/openwfe/contextual.rb +111 -0
  17. data/lib/openwfe/def.rb +46 -0
  18. data/lib/openwfe/engine.rb +37 -0
  19. data/lib/openwfe/engine/engine.rb +756 -0
  20. data/lib/openwfe/engine/expool_methods.rb +172 -0
  21. data/lib/openwfe/engine/file_persisted_engine.rb +105 -0
  22. data/lib/openwfe/engine/participant_methods.rb +133 -0
  23. data/lib/openwfe/engine/status_methods.rb +353 -0
  24. data/lib/openwfe/engine/update_exp_methods.rb +112 -0
  25. data/lib/openwfe/exceptions.rb +51 -0
  26. data/lib/openwfe/expool/errorjournal.rb +476 -0
  27. data/lib/openwfe/expool/expressionpool.rb +1144 -0
  28. data/lib/openwfe/expool/expstorage.rb +403 -0
  29. data/lib/openwfe/expool/history.rb +174 -0
  30. data/lib/openwfe/expool/journal.rb +224 -0
  31. data/lib/openwfe/expool/journal_replay.rb +321 -0
  32. data/lib/openwfe/expool/parser.rb +242 -0
  33. data/lib/openwfe/expool/representation.rb +121 -0
  34. data/lib/openwfe/expool/threadedexpstorage.rb +188 -0
  35. data/lib/openwfe/expool/wfidgen.rb +388 -0
  36. data/lib/openwfe/expool/yamlexpstorage.rb +224 -0
  37. data/lib/openwfe/expressions/condition.rb +244 -0
  38. data/lib/openwfe/expressions/environment.rb +246 -0
  39. data/lib/openwfe/expressions/expressionmap.rb +258 -0
  40. data/lib/openwfe/expressions/fe_cancel.rb +109 -0
  41. data/lib/openwfe/expressions/fe_command.rb +241 -0
  42. data/lib/openwfe/expressions/fe_concurrence.rb +662 -0
  43. data/lib/openwfe/expressions/fe_cron.rb +259 -0
  44. data/lib/openwfe/expressions/fe_cursor.rb +259 -0
  45. data/lib/openwfe/expressions/fe_define.rb +192 -0
  46. data/lib/openwfe/expressions/fe_do.rb +168 -0
  47. data/lib/openwfe/expressions/fe_equals.rb +291 -0
  48. data/lib/openwfe/expressions/fe_filter.rb +129 -0
  49. data/lib/openwfe/expressions/fe_filter_definition.rb +168 -0
  50. data/lib/openwfe/expressions/fe_fqv.rb +250 -0
  51. data/lib/openwfe/expressions/fe_if.rb +303 -0
  52. data/lib/openwfe/expressions/fe_iterator.rb +145 -0
  53. data/lib/openwfe/expressions/fe_listen.rb +371 -0
  54. data/lib/openwfe/expressions/fe_losfor.rb +111 -0
  55. data/lib/openwfe/expressions/fe_misc.rb +421 -0
  56. data/lib/openwfe/expressions/fe_participant.rb +269 -0
  57. data/lib/openwfe/expressions/fe_reserve.rb +212 -0
  58. data/lib/openwfe/expressions/fe_save.rb +274 -0
  59. data/lib/openwfe/expressions/fe_sequence.rb +117 -0
  60. data/lib/openwfe/expressions/fe_set.rb +139 -0
  61. data/lib/openwfe/expressions/fe_sleep.rb +166 -0
  62. data/lib/openwfe/expressions/fe_step.rb +159 -0
  63. data/lib/openwfe/expressions/fe_subprocess.rb +168 -0
  64. data/lib/openwfe/expressions/fe_timeout.rb +127 -0
  65. data/lib/openwfe/expressions/fe_wait.rb +78 -0
  66. data/lib/openwfe/expressions/fe_when.rb +142 -0
  67. data/lib/openwfe/expressions/filter.rb +104 -0
  68. data/lib/openwfe/expressions/flowexpression.rb +847 -0
  69. data/lib/openwfe/expressions/iterator.rb +221 -0
  70. data/lib/openwfe/expressions/merge.rb +84 -0
  71. data/lib/openwfe/expressions/raw.rb +547 -0
  72. data/lib/openwfe/expressions/rprocdef.rb +375 -0
  73. data/lib/openwfe/expressions/time.rb +333 -0
  74. data/lib/openwfe/expressions/timeout.rb +178 -0
  75. data/lib/openwfe/expressions/value.rb +126 -0
  76. data/lib/openwfe/filterdef.rb +259 -0
  77. data/lib/openwfe/flowexpressionid.rb +357 -0
  78. data/lib/openwfe/listeners/listener.rb +97 -0
  79. data/lib/openwfe/listeners/listeners.rb +139 -0
  80. data/lib/openwfe/listeners/socketlisteners.rb +272 -0
  81. data/lib/openwfe/logging.rb +122 -0
  82. data/lib/openwfe/omixins.rb +95 -0
  83. data/lib/openwfe/orest/controlclient.rb +119 -0
  84. data/lib/openwfe/orest/definitions.rb +113 -0
  85. data/lib/openwfe/orest/exception.rb +60 -0
  86. data/lib/openwfe/orest/oldrestservlet.rb +279 -0
  87. data/lib/openwfe/orest/osocket.rb +148 -0
  88. data/lib/openwfe/orest/restclient.rb +176 -0
  89. data/lib/openwfe/orest/workitem.rb +206 -0
  90. data/lib/openwfe/orest/worklistclient.rb +272 -0
  91. data/lib/openwfe/orest/xmlcodec.rb +670 -0
  92. data/lib/openwfe/participants.rb +38 -0
  93. data/lib/openwfe/participants/enoparticipants.rb +230 -0
  94. data/lib/openwfe/participants/participant.rb +141 -0
  95. data/lib/openwfe/participants/participantmap.rb +249 -0
  96. data/lib/openwfe/participants/participants.rb +407 -0
  97. data/lib/openwfe/participants/soapparticipants.rb +135 -0
  98. data/lib/openwfe/participants/socketparticipants.rb +202 -0
  99. data/lib/openwfe/participants/storeparticipants.rb +254 -0
  100. data/lib/openwfe/rudefinitions.rb +130 -0
  101. data/lib/openwfe/service.rb +103 -0
  102. data/lib/openwfe/storage/yamlcustom.rb +106 -0
  103. data/lib/openwfe/storage/yamlfilestorage.rb +245 -0
  104. data/lib/openwfe/tools/flowtracer.rb +81 -0
  105. data/lib/openwfe/util/dollar.rb +217 -0
  106. data/lib/openwfe/util/irb.rb +86 -0
  107. data/lib/openwfe/util/observable.rb +144 -0
  108. data/lib/openwfe/util/ometa.rb +62 -0
  109. data/lib/openwfe/util/workqueue.rb +124 -0
  110. data/lib/openwfe/util/xml.rb +418 -0
  111. data/lib/openwfe/utils.rb +554 -0
  112. data/lib/openwfe/version.rb +37 -0
  113. data/lib/openwfe/workitem.rb +499 -0
  114. data/lib/openwfe/worklist/oldrest.rb +244 -0
  115. data/lib/openwfe/worklist/storelocks.rb +293 -0
  116. data/lib/openwfe/worklist/storeparticipant.rb +44 -0
  117. data/lib/openwfe/worklist/worklist.rb +297 -0
  118. data/test/README.txt +27 -0
  119. data/test/back_0916_test.rb +111 -0
  120. data/test/bm/bm_1_xml_vs_prog.rb +56 -0
  121. data/test/bm/bm_2_step.rb +109 -0
  122. data/test/bm/ft_0f_5ms.rb +35 -0
  123. data/test/bm/ft_26_load.rb +210 -0
  124. data/test/bm/ft_26b_load.rb +86 -0
  125. data/test/bm/ft_26c_load.rb +97 -0
  126. data/test/bm/ft_26d_load.rb +97 -0
  127. data/test/bm/ft_recu.rb +71 -0
  128. data/test/clone_test.rb +122 -0
  129. data/test/concurrence_test.rb +77 -0
  130. data/test/condition_test.rb +155 -0
  131. data/test/console_test.rb +12 -0
  132. data/test/cron_ltest.rb +15 -0
  133. data/test/description_test.rb +87 -0
  134. data/test/eno_test.rb +76 -0
  135. data/test/expmap_test.rb +54 -0
  136. data/test/expool_20031219_0916.tgz +0 -0
  137. data/test/fe_lookup_att_test.rb +62 -0
  138. data/test/fei_test.rb +181 -0
  139. data/test/file_persisted_engine_test.rb +64 -0
  140. data/test/file_persistence_test.rb +134 -0
  141. data/test/filep_cancel_test.rb +123 -0
  142. data/test/filter_test.rb +109 -0
  143. data/test/flowtestbase.rb +351 -0
  144. data/test/ft_0.rb +68 -0
  145. data/test/ft_0b_sequence.rb +36 -0
  146. data/test/ft_0c_testname.rb +33 -0
  147. data/test/ft_0d_participant.rb +30 -0
  148. data/test/ft_0e_multibody.rb +34 -0
  149. data/test/ft_10_loop.rb +134 -0
  150. data/test/ft_11_ppd.rb +415 -0
  151. data/test/ft_11b_ppd.rb +54 -0
  152. data/test/ft_12_blockparticipant.rb +97 -0
  153. data/test/ft_13_eno.rb +52 -0
  154. data/test/ft_14_subprocess.rb +88 -0
  155. data/test/ft_14b_subprocess.rb +192 -0
  156. data/test/ft_14c_subprocess.rb +68 -0
  157. data/test/ft_15_iterator.rb +216 -0
  158. data/test/ft_15b_iterator.rb +74 -0
  159. data/test/ft_16_fqv.rb +73 -0
  160. data/test/ft_17_condition.rb +84 -0
  161. data/test/ft_18_pname.rb +56 -0
  162. data/test/ft_1_unset.rb +175 -0
  163. data/test/ft_1b_unset.rb +39 -0
  164. data/test/ft_20_cron.rb +53 -0
  165. data/test/ft_21_cron.rb +87 -0
  166. data/test/ft_21b_cron_pause.rb +82 -0
  167. data/test/ft_22_history.rb +74 -0
  168. data/test/ft_23_when.rb +77 -0
  169. data/test/ft_23b_when.rb +70 -0
  170. data/test/ft_23c_wait.rb +80 -0
  171. data/test/ft_23d_cww.rb +58 -0
  172. data/test/ft_24_def.rb +44 -0
  173. data/test/ft_25_cancel.rb +89 -0
  174. data/test/ft_27_getflowpos.rb +147 -0
  175. data/test/ft_28_fileparticipant.rb +63 -0
  176. data/test/ft_29_httprb.rb +106 -0
  177. data/test/ft_2_concurrence.rb +135 -0
  178. data/test/ft_2b_concurrence.rb +188 -0
  179. data/test/ft_2c_concurrence.rb +64 -0
  180. data/test/ft_30_socketlistener.rb +203 -0
  181. data/test/ft_31_flowname.rb +40 -0
  182. data/test/ft_32_journal.rb +91 -0
  183. data/test/ft_32c_journal.rb +102 -0
  184. data/test/ft_32d_journal.rb +84 -0
  185. data/test/ft_33_description.rb +107 -0
  186. data/test/ft_34_cancelwfid.rb +80 -0
  187. data/test/ft_35_localdefs.rb +75 -0
  188. data/test/ft_36_subprocids.rb +97 -0
  189. data/test/ft_37_pnames.rb +70 -0
  190. data/test/ft_38_tag.rb +127 -0
  191. data/test/ft_38b_tag.rb +161 -0
  192. data/test/ft_38c_tag.rb +100 -0
  193. data/test/ft_39_reserve.rb +63 -0
  194. data/test/ft_39b_reserve.rb +84 -0
  195. data/test/ft_3_equals.rb +170 -0
  196. data/test/ft_3b_lookup_vf.rb +83 -0
  197. data/test/ft_40_defined.rb +61 -0
  198. data/test/ft_41_case.rb +110 -0
  199. data/test/ft_42_environments.rb +75 -0
  200. data/test/ft_43_pat10.rb +85 -0
  201. data/test/ft_44_save.rb +70 -0
  202. data/test/ft_44b_restore.rb +212 -0
  203. data/test/ft_45_citerator.rb +214 -0
  204. data/test/ft_46_pparams.rb +62 -0
  205. data/test/ft_47_filter.rb +160 -0
  206. data/test/ft_48_fe_filter.rb +88 -0
  207. data/test/ft_49_condition.rb +126 -0
  208. data/test/ft_4_misc.rb +237 -0
  209. data/test/ft_50_xml_attribute.rb +155 -0
  210. data/test/ft_51_stack.rb +55 -0
  211. data/test/ft_52_obs_participant.rb +123 -0
  212. data/test/ft_53_null_noop_participant.rb +62 -0
  213. data/test/ft_54_listen.rb +288 -0
  214. data/test/ft_54b_listen.rb +66 -0
  215. data/test/ft_54c_listen.rb +99 -0
  216. data/test/ft_55_ptimeout.rb +59 -0
  217. data/test/ft_56_timeout.rb +59 -0
  218. data/test/ft_57_a.rb +145 -0
  219. data/test/ft_58_ejournal.rb +151 -0
  220. data/test/ft_59_ps.rb +150 -0
  221. data/test/ft_59b_ps_for_pat.rb +58 -0
  222. data/test/ft_5_time.rb +118 -0
  223. data/test/ft_60_ecancel.rb +161 -0
  224. data/test/ft_61_elsub.rb +51 -0
  225. data/test/ft_62_procparticipant.rb +71 -0
  226. data/test/ft_63_pause.rb +124 -0
  227. data/test/ft_64_alias.rb +102 -0
  228. data/test/ft_64_clone.rb +69 -0
  229. data/test/ft_65_stringlaunch.rb +59 -0
  230. data/test/ft_66_subforget.rb +70 -0
  231. data/test/ft_67_schedlaunch.rb +116 -0
  232. data/test/ft_68_ifparticipant.rb +70 -0
  233. data/test/ft_69_cancelmissing.rb +51 -0
  234. data/test/ft_6_lambda.rb +64 -0
  235. data/test/ft_70_lookupvar.rb +55 -0
  236. data/test/ft_71_log.rb +60 -0
  237. data/test/ft_72_lookup_processes.rb +76 -0
  238. data/test/ft_73_cancel_sub.rb +139 -0
  239. data/test/ft_74_block_and_workitem_dup.rb +63 -0
  240. data/test/ft_75_ruby_attributes.rb +87 -0
  241. data/test/ft_76_merge_isolate.rb +88 -0
  242. data/test/ft_77_segments.rb +35 -0
  243. data/test/ft_78_eval.rb +150 -0
  244. data/test/ft_79_tticket.rb +187 -0
  245. data/test/ft_79b_tticket.rb +172 -0
  246. data/test/ft_79c_outcome.rb +56 -0
  247. data/test/ft_7_lose.rb +104 -0
  248. data/test/ft_7b_lose.rb +78 -0
  249. data/test/ft_80_spname.rb +91 -0
  250. data/test/ft_81_exp.rb +60 -0
  251. data/test/ft_82_trecu.rb +46 -0
  252. data/test/ft_83_badpause.rb +58 -0
  253. data/test/ft_84_updateexp.rb +198 -0
  254. data/test/ft_85_dolhash.rb +43 -0
  255. data/test/ft_86_dollar_fv.rb +68 -0
  256. data/test/ft_87_define.rb +74 -0
  257. data/test/ft_8_forget.rb +44 -0
  258. data/test/ft_9_cursor.rb +145 -0
  259. data/test/ft_9b_cursor.rb +105 -0
  260. data/test/ft_tests.rb +124 -0
  261. data/test/hash_test.rb +75 -0
  262. data/test/hparticipant_test.rb +164 -0
  263. data/test/lookup_att_test.rb +90 -0
  264. data/test/lookup_vf_test.rb +94 -0
  265. data/test/misc_test.rb +90 -0
  266. data/test/nut_0_irb.rb +20 -0
  267. data/test/obs_test.rb +142 -0
  268. data/test/orest_test.rb +251 -0
  269. data/test/param_test.rb +290 -0
  270. data/test/participant_test.rb +101 -0
  271. data/test/pending.rb +23 -0
  272. data/test/ps_representation.rb +133 -0
  273. data/test/rake_ltest.rb +38 -0
  274. data/test/rake_qtest.rb +68 -0
  275. data/test/raw_prog_test.rb +412 -0
  276. data/test/restart_cron_test.rb +136 -0
  277. data/test/restart_paused_test.rb +98 -0
  278. data/test/restart_sleep_test.rb +140 -0
  279. data/test/restart_tests.rb +18 -0
  280. data/test/restart_when_test.rb +112 -0
  281. data/test/ruby_procdef_test.rb +132 -0
  282. data/test/rutest_utils.rb +63 -0
  283. data/test/sec_test.rb +205 -0
  284. data/test/slock_test.rb +80 -0
  285. data/test/storage_test.rb +44 -0
  286. data/test/test.rb +3 -0
  287. data/test/timeout_test.rb +105 -0
  288. data/test/util_xml_test.rb +112 -0
  289. data/test/wfid_test.rb +175 -0
  290. data/test/wi_test.rb +75 -0
  291. metadata +433 -0
@@ -0,0 +1,112 @@
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
+ module OpenWFE
41
+
42
+ #
43
+ # The methods of the engine for updating live expressions
44
+ # (in flight modifications of process instances)
45
+ #
46
+ module UpdateExpMethods
47
+
48
+ #
49
+ # Use only when doing "process gardening".
50
+ #
51
+ # This method updates an expression, the 'data' parameter is expected
52
+ # to be a hash. If the expression is an Environment, the variables
53
+ # will be merged with the ones found in the data param.
54
+ # If the expression is not an Environment, the data will be merged
55
+ # into the 'applied_workitem' if any.
56
+ #
57
+ # If the merge is not possible, an exception will be raised.
58
+ #
59
+ def update_expression_data (fei, data)
60
+
61
+ fexp = fetch_exp fei
62
+
63
+ original = if fexp.is_a?(Environment)
64
+
65
+ fexp.variables
66
+ else
67
+
68
+ fexp.applied_workitem.attributes
69
+ end
70
+
71
+ original.merge! data
72
+
73
+ get_expression_pool.update fexp
74
+ end
75
+
76
+ #
77
+ # A variant of update_expression() that directly replaces
78
+ # the raw representation stored within a RawExpression.
79
+ #
80
+ # Useful for modifying [not yet reached] segments of processes.
81
+ #
82
+ def update_raw_expression (fei, representation)
83
+
84
+ fexp = fetch_exp fei
85
+
86
+ raise "cannot update already applied expression" \
87
+ unless fexp.is_a?(RawExpression)
88
+
89
+ fexp.raw_representation = representation
90
+ fexp.raw_rep_updated = true
91
+
92
+ get_expression_pool.update fexp
93
+ end
94
+
95
+ #
96
+ # Replaces an expression in the pool with a newer version of it.
97
+ #
98
+ # (useful when fixing processes on the fly)
99
+ #
100
+ def update_expression (fexp)
101
+
102
+ fexp.application_context = application_context
103
+
104
+ fexp.raw_rep_updated = true
105
+
106
+ get_expression_pool.update fexp
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
@@ -0,0 +1,51 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2007, 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@openwfe.org
38
+ #
39
+
40
+
41
+ module OpenWFE
42
+
43
+ #
44
+ # The exception thrown at launch time, when there are parameter missing
45
+ # or whose value isn't matching what is required.
46
+ #
47
+ class ParameterException < Exception
48
+ end
49
+
50
+ end
51
+
@@ -0,0 +1,476 @@
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 'find'
41
+ require 'fileutils'
42
+
43
+ require 'openwfe/service'
44
+ require 'openwfe/omixins'
45
+ require 'openwfe/rudefinitions'
46
+
47
+
48
+ module OpenWFE
49
+
50
+ #
51
+ # Encapsulating process error information.
52
+ #
53
+ # Instances of this class may be used to replay_at_error
54
+ #
55
+ class ProcessError
56
+
57
+ #
58
+ # When did the error occur.
59
+ #
60
+ attr_reader :date
61
+
62
+ #
63
+ # The FlowExpressionId instance uniquely pointing at the expression
64
+ # which 'failed'.
65
+ #
66
+ attr_reader :fei
67
+
68
+ #
69
+ # Generally something like :apply or :reply
70
+ #
71
+ attr_reader :message
72
+
73
+ #
74
+ # The workitem accompanying the message (apply(workitem) /
75
+ # reply (workitem)).
76
+ #
77
+ attr_reader :workitem
78
+
79
+ #
80
+ # The String stack trace of the error.
81
+ #
82
+ attr_reader :stacktrace
83
+
84
+ #
85
+ # The error class (String) of the top level error
86
+ #
87
+ attr_reader :error_class
88
+
89
+ def initialize (*args)
90
+
91
+ @date = Time.new
92
+ @fei, @message, @workitem, @error_class, @stacktrace = args
93
+ end
94
+
95
+ #
96
+ # Returns the parent workflow instance id (process id) of this
97
+ # ProcessError instance.
98
+ #
99
+ def wfid
100
+ @fei.parent_wfid
101
+ end
102
+
103
+ alias :parent_wfid :wfid
104
+
105
+ #
106
+ # Produces a human readable version of the information in the
107
+ # ProcessError instance.
108
+ #
109
+ def to_s
110
+ s = ""
111
+ s << "-- #{self.class.name} --\n"
112
+ s << " date : #{@date}\n"
113
+ s << " fei : #{@fei}\n"
114
+ s << " message : #{@message}\n"
115
+ s << " workitem : ...\n"
116
+ s << " error_class : #{@error_class}\n"
117
+ s << " stacktrace : #{@stacktrace[0, 80]}\n"
118
+ s
119
+ end
120
+
121
+ #
122
+ # Returns a hash
123
+ #
124
+ def hash
125
+ to_s.hash
126
+ #
127
+ # a bit costly but as it's only used by resume_process()...
128
+ end
129
+
130
+ #
131
+ # Returns true if the other instance is a ProcessError and is the
132
+ # same error as this one.
133
+ #
134
+ def == (other)
135
+ return false unless other.is_a?(ProcessError)
136
+ return to_s == other.to_s
137
+ #
138
+ # a bit costly but as it's only used by resume_process()...
139
+ end
140
+ end
141
+
142
+ #
143
+ # This is a base class for all error journal, don't instantiate,
144
+ # work rather with InMemoryErrorJournal (only for testing envs though),
145
+ # or YamlErrorJournal.
146
+ #
147
+ class ErrorJournal < Service
148
+ include OwfeServiceLocator
149
+ include FeiMixin
150
+
151
+ def initialize (service_name, application_context)
152
+
153
+ super
154
+
155
+ get_expression_pool.add_observer :error do |event, *args|
156
+ #
157
+ # logs each error occurring in the expression pool
158
+
159
+ begin
160
+
161
+ record_error(ProcessError.new(*args))
162
+
163
+ rescue Exception => e
164
+ lwarn { "*** process error : \n" + args.join("\n") }
165
+ end
166
+ end
167
+
168
+ get_expression_pool.add_observer :terminate do |event, *args|
169
+ #
170
+ # removes error log when a process terminates
171
+
172
+ fei = args[0].fei
173
+
174
+ remove_error_log fei.wfid \
175
+ if fei.is_in_parent_process?
176
+ end
177
+ end
178
+
179
+ #
180
+ # Returns true if the given wfid (or fei) (process instance id)
181
+ # has had errors.
182
+ #
183
+ def has_errors? (wfid)
184
+
185
+ get_error_log(wfid).size > 0
186
+ end
187
+
188
+ #--
189
+ #
190
+ # Commented out : has no real value
191
+ #
192
+ # Replays the given process instance (wfid or fei) at its last
193
+ # recorded error.
194
+ #
195
+ # There is an optional 'offset' parameter. Its default value is '0'.
196
+ # Which means that the replay will occur at the last error.
197
+ #
198
+ # ejournal.replay_at_last_error('20070630-hiwakuzara', 1)
199
+ #
200
+ # Will replay a given process instance at its 1 to last error.
201
+ #
202
+ #def replay_at_last_error (wfid, offset=0)
203
+ # wfid = extract_wfid(wfid)
204
+ # log = get_error_log(wfid)
205
+ # index = (-1 - offset)
206
+ # error = log[index]
207
+ # raise "no error for process '#{wfid}' at offset #{offset}" \
208
+ # unless error
209
+ # replay_at_error error
210
+ #end
211
+ #++
212
+
213
+ #--
214
+ #
215
+ # Moved to the engine itself.
216
+ #
217
+ # Replays at a specific error (fetched with read_error_log()).
218
+ #
219
+ #def replay_at_error (error)
220
+ # get_expression_pool.queue_work(
221
+ # error.message,
222
+ # error.fei,
223
+ # error.workitem)
224
+ #end
225
+ #++
226
+
227
+ #
228
+ # A utility method : given a list of errors, will make sure that for
229
+ # each flow expression only one expression (the most recent) will get
230
+ # listed.
231
+ # Returns a list of errors, from the oldest to the most recent.
232
+ #
233
+ # Could be useful when considering a process where multiple replay
234
+ # attempts failed.
235
+ #
236
+ def ErrorJournal.reduce_error_list (errors)
237
+
238
+ h = {}
239
+
240
+ errors.each do |e|
241
+ h[e.fei] = e
242
+ #
243
+ # last errors do override previous errors for the
244
+ # same fei
245
+ end
246
+
247
+ h.values.sort do |error_a, error_b|
248
+ error_a.date <=> error_b.date
249
+ end
250
+ end
251
+ end
252
+
253
+ #
254
+ # Stores all the errors in a hash... For testing purposes only, like
255
+ # the InMemoryExpressionStorage.
256
+ #
257
+ class InMemoryErrorJournal < ErrorJournal
258
+
259
+ def initialize (service_name, application_context)
260
+
261
+ super
262
+
263
+ @per_processes = {}
264
+ end
265
+
266
+ #
267
+ # Returns a list (older first) of the errors for a process
268
+ # instance identified by its fei or wfid.
269
+ #
270
+ # Will return an empty list if there a no errors for the process
271
+ # instances.
272
+ #
273
+ def get_error_log (wfid)
274
+
275
+ wfid = extract_wfid wfid, true
276
+ @per_processes[wfid] or []
277
+ end
278
+
279
+ #
280
+ # Removes the error log for a process instance.
281
+ #
282
+ def remove_error_log (wfid)
283
+
284
+ wfid = extract_wfid wfid, true
285
+ @per_processes.delete(wfid)
286
+ end
287
+
288
+ #
289
+ # Removes a list of errors from the error journal.
290
+ #
291
+ # The 'errors' parameter may be a single error (instead of an array).
292
+ #
293
+ def remove_errors (wfid, errors)
294
+
295
+ errors = Array(errors)
296
+
297
+ log = get_error_log wfid
298
+
299
+ errors.each do |e|
300
+ log.delete e
301
+ end
302
+ end
303
+
304
+ #
305
+ # Reads all the error logs currently stored.
306
+ # Returns a hash wfid --> error list.
307
+ #
308
+ def get_error_logs
309
+
310
+ @per_processes
311
+ end
312
+
313
+ protected
314
+
315
+ def record_error (error)
316
+
317
+ (@per_processes[error.wfid] ||= []) << error
318
+ # not that unreadable after all...
319
+ end
320
+ end
321
+
322
+ #
323
+ # A Journal that only keep track of error in process execution.
324
+ #
325
+ class YamlErrorJournal < ErrorJournal
326
+
327
+ attr_reader :workdir
328
+
329
+ def initialize (service_name, application_context)
330
+
331
+ require 'openwfe/storage/yamlcustom'
332
+ # making sure this file has been required at this point
333
+ # this yamlcustom thing prevents the whole OpenWFE ecosystem
334
+ # to get serialized :)
335
+
336
+ super
337
+
338
+ @workdir = get_work_directory + "/ejournal"
339
+
340
+ FileUtils.makedirs(@workdir) unless File.exist?(@workdir)
341
+ end
342
+
343
+ #
344
+ # Returns a list (older first) of the errors for a process
345
+ # instance identified by its fei or wfid.
346
+ #
347
+ # Will return an empty list if there a no errors for the process
348
+ # instances.
349
+ #
350
+ def get_error_log (wfid)
351
+
352
+ path = get_path wfid
353
+
354
+ return [] unless File.exist?(path)
355
+
356
+ read_error_log_from path
357
+ end
358
+
359
+ #
360
+ # Copies the error log of a process instance to a give path (and
361
+ # filename).
362
+ #
363
+ # Could be useful when one has to perform replay operations and wants
364
+ # to keep a copy of the original error[s].
365
+ #
366
+ def copy_error_log_to (wfid, path)
367
+
368
+ original_path = get_path wfid
369
+ FileUtils.copy_file original_path, path
370
+ end
371
+
372
+ #
373
+ # Reads an error log from a specific file (possibly as copied over
374
+ # via copy_error_log_to()).
375
+ #
376
+ def read_error_log_from (path)
377
+
378
+ raise "no error log file at #{path}" unless File.exist?(path)
379
+
380
+ File.open(path) do |f|
381
+ s = YAML.load_stream f
382
+ s.documents
383
+ end
384
+ end
385
+
386
+ #
387
+ # Removes the error log of a specific process instance.
388
+ # Could be a good idea after a succesful replay operation.
389
+ #
390
+ # 'wfid' may be either a workflow instance id (String) either
391
+ # a FlowExpressionId instance.
392
+ #
393
+ def remove_error_log (wfid)
394
+
395
+ path = get_path wfid
396
+
397
+ File.delete(path) if File.exist?(path)
398
+ end
399
+
400
+ #
401
+ # Removes a list of errors from this error journal.
402
+ #
403
+ def remove_errors (wfid, errors)
404
+
405
+ errors = Array(errors)
406
+
407
+ # load all errors
408
+
409
+ log = get_error_log wfid
410
+
411
+ # remove the given errors
412
+
413
+ errors.each do |e|
414
+ log.delete e
415
+ end
416
+
417
+ # rewrite error file
418
+
419
+ path = get_path wfid
420
+
421
+ if log.size > 0
422
+
423
+ File.open(path, "w") do |f|
424
+ log.each do |e|
425
+ f.puts e.to_yaml
426
+ end
427
+ end
428
+ else
429
+
430
+ File.delete path
431
+ end
432
+ end
433
+
434
+ #
435
+ # Reads all the error logs currently stored.
436
+ # Returns a hash wfid --> error list.
437
+ #
438
+ def get_error_logs
439
+
440
+ result = {}
441
+
442
+ Find.find(@workdir) do |path|
443
+ next unless path.endswith(".ejournal")
444
+ wfid = path[0..-9]
445
+ log = read_error_log wfid
446
+ result[wfid] = log
447
+ end
448
+
449
+ result
450
+ end
451
+
452
+ protected
453
+
454
+ #
455
+ # logs the error as a yaml string in an error log file
456
+ # (there is one error log file per workflow instance).
457
+ #
458
+ def record_error (error)
459
+
460
+ path = get_path error.fei
461
+
462
+ File.open(path, "a+") do |f|
463
+ f.puts error.to_yaml
464
+ end
465
+ end
466
+
467
+ #
468
+ # Returns the path to the error log file of a specific process
469
+ # instance.
470
+ #
471
+ def get_path (fei_or_wfid)
472
+
473
+ @workdir + "/" + extract_wfid(fei_or_wfid, true) + ".ejournal"
474
+ end
475
+ end
476
+ end