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,388 @@
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 'thread'
41
+
42
+ require 'rufus/mnemo'
43
+
44
+ require 'openwfe/service'
45
+ require 'openwfe/rudefinitions'
46
+
47
+
48
+ module OpenWFE
49
+
50
+ #
51
+ # This default wfid generator outputs a long integer as a String.
52
+ # The last given id (in order to prevent clocks being put back) is
53
+ # stored in the work directory in the file "wfidgen.last"
54
+ #
55
+ class DefaultWfidGenerator < Service
56
+
57
+ def initialize (service_name, application_context)
58
+
59
+ super
60
+
61
+ @last = -1
62
+ @mutex = Mutex.new
63
+
64
+ @last_fn = get_work_directory + '/wfidgen.last'
65
+
66
+ load_last()
67
+
68
+ ensure_last_f
69
+ end
70
+
71
+ #
72
+ # Returns a new workflow instance id
73
+ #
74
+ # The launchitem parameter is not used by this generator.
75
+ #
76
+ def generate (launchitem=nil)
77
+
78
+ wfid = nil
79
+
80
+ @mutex.synchronize do
81
+ wfid = now
82
+ wfid = @last + 1 if wfid <= @last
83
+ @last = wfid
84
+ save_last
85
+ end
86
+
87
+ to_string(wfid)
88
+ end
89
+
90
+ #
91
+ # The actual job of turning the numeric result into a String.
92
+ # This method is overriden in extension of this class.
93
+ #
94
+ def to_string (numeric_id)
95
+
96
+ numeric_id.to_s
97
+ end
98
+
99
+ #
100
+ # Is a simple call to OpenWFE::split_wfid()
101
+ #
102
+ def split_wfid (wfid)
103
+
104
+ OpenWFE.split_wfid(wfid)
105
+ end
106
+
107
+ #
108
+ # This method is called by OpenWFE::split_wfid() when it has detected
109
+ # a wfid following this 'defaut' scheme.
110
+ #
111
+ def self.split_wfid (wfid)
112
+
113
+ r = []
114
+ 0.upto(wfid.length-1) do |i|
115
+ r << wfid[i, 1]
116
+ end
117
+
118
+ r
119
+ end
120
+
121
+ #
122
+ # Stops this service.
123
+ # In this particular implementation, makes sure the "wfidgen.last"
124
+ # file is closed.
125
+ #
126
+ def stop
127
+
128
+ #linfo { "stop() stopping '#{@service_name}'" }
129
+ @last_f.close if @last_f
130
+ end
131
+
132
+ protected
133
+
134
+ def ensure_last_f
135
+ if (not @last_f) or @last_f.closed?
136
+ begin
137
+ @last_f = File.open(@last_fn, "w+")
138
+ rescue Exception => e
139
+ lwarn do
140
+ "new() failed to open #{@last_fn}, "+
141
+ "continuing anyway...\n"+
142
+ OpenWFE::exception_to_s(e)
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ def now
149
+ wfid = Time.now.to_f * 1000 * 10
150
+ wfid.to_i
151
+ end
152
+
153
+ def save_last
154
+ return unless @last_f
155
+ ensure_last_f()
156
+ @last_f.pos = 0
157
+ @last_f.puts @last
158
+ end
159
+
160
+ def load_last
161
+ @mutex.synchronize do
162
+
163
+ if File.exist?(@last_fn)
164
+ begin
165
+ s = File.open(@last_fn, "r") do |f|
166
+ f.readline
167
+ end
168
+ @last = Integer(s)
169
+ #puts @last
170
+ rescue Exception => e
171
+ #puts
172
+ #puts e.to_s
173
+ end
174
+ end
175
+
176
+ n = now
177
+
178
+ @last = n if (not @last) or (@last < n)
179
+ end
180
+ end
181
+ end
182
+
183
+ #
184
+ # This extension of DefaultWfidGenerator produces ids like
185
+ # "20070318-jonowoguya" or "20071224-jesoshimoha" that are a bit
186
+ # easier to grasp than full integer wfids.
187
+ #
188
+ # Now relying on the 'rufus-mnemo' gem.
189
+ #
190
+ class KotobaWfidGenerator < DefaultWfidGenerator
191
+
192
+ #
193
+ # Overrides the to_string() method of the DefaultWfidGenerator,
194
+ #
195
+ def to_string (numeric_id)
196
+
197
+ self.class.to_string(numeric_id)
198
+ end
199
+
200
+ #
201
+ # That's here that the numeric wfid gets turned into a 'kotoba'.
202
+ # A static method easily accessible by any.
203
+ #
204
+ def self.to_string (numeric_id)
205
+
206
+ i = numeric_id % (10 * 1000 * 60 * 60 * 24)
207
+ t = Time.now.gmtime
208
+
209
+ s = sprintf "%4d%02d%02d", t.year, t.month, t.day
210
+ s << "-"
211
+ s << Rufus::Mnemo::from_integer(i)
212
+ s
213
+ end
214
+
215
+ #
216
+ # This method is called by OpenWFE::split_wfid() when it has detected
217
+ # a wfid following the 'kotoba' scheme.
218
+ # Returns the 'kotoba' wfid split into its syllables
219
+ #
220
+ def self.split_wfid (wfid)
221
+
222
+ Rufus::Mnemo::split(wfid[9..-1])
223
+ end
224
+
225
+ #
226
+ # Turns a KotobaWfidGenerator produced wfid into a UTC date.
227
+ #
228
+ def self.to_time (wfid)
229
+
230
+ year = wfid[0, 4]
231
+ month = wfid[4, 2]
232
+ day = wfid[6, 2]
233
+
234
+ s = wfid[9..-1]
235
+
236
+ i = Rufus::Mnemo::to_integer(s)
237
+
238
+ hour = (i / (10000 * 60 * 60)) % 24
239
+ min = (i / (10000 * 60)) % 60
240
+ sec = (i / 10000) % 60
241
+ usec = (i * 100) % 1000000
242
+
243
+ #puts "hms #{hour} #{min} #{sec} #{usec}"
244
+
245
+ Time.utc(year, month, day, hour, min, sec, usec)
246
+ end
247
+
248
+ def self.from_time (t)
249
+
250
+ to_string(t.to_f * 10 * 1000).to_i
251
+ end
252
+ end
253
+
254
+ #
255
+ # This wfid generator returns as wfid the value found in a given
256
+ # field of the launchitem (if any).
257
+ #
258
+ # If there is no launchitem or no field, a Kotoba wfid is returned.
259
+ #
260
+ # This generator is useful for engines that have to use workflow
261
+ # instance ids generated by other systems.
262
+ #
263
+ class FieldWfidGenerator < KotobaWfidGenerator
264
+
265
+ def initialize (service_name, application_context, field_name)
266
+
267
+ super service_name, application_context
268
+
269
+ @field_name = field_name
270
+ end
271
+
272
+ def generate (launchitem=nil)
273
+
274
+ return super unless launchitem
275
+
276
+ wfid = launchitem.attributes[@field_name]
277
+
278
+ return wfid.to_s if wfid
279
+
280
+ super
281
+ #
282
+ # if the field is not present in the launchitem, will
283
+ # return a Kotoba wfid
284
+ end
285
+ end
286
+
287
+ #
288
+ # A wfid generator that uses any underlying "uuidgen" command it might
289
+ # find.
290
+ # By default, it favours "uuidgen -t".
291
+ #
292
+ # You can specifying a command by passing a :uuid_command param in the
293
+ # application context, or simply by overriding the generate() method.
294
+ #
295
+ class UuidWfidGenerator < Service
296
+
297
+ COMMANDS = [
298
+ "uuidgen -t",
299
+ "uuidgen"
300
+ ]
301
+
302
+ def initialize (service_name, application_context)
303
+
304
+ super
305
+
306
+ @command = @application_context[:uuid_command] \
307
+ if @application_context
308
+
309
+ unless @command
310
+ COMMANDS.each do |c|
311
+ c = "#{c} 2> /dev/null"
312
+ s = `#{c}`
313
+ h = s[0, 8].hex
314
+ if h > 0
315
+ @command = c
316
+ break
317
+ end
318
+ end
319
+ end
320
+
321
+ raise "no command found for generating an uuid found..." \
322
+ unless @command
323
+
324
+ linfo { "new() command that will be used : '#{@command}'" }
325
+ end
326
+
327
+ #
328
+ # Generates a brand new UUID
329
+ #
330
+ # The launchitem parameter is not used by this generator.
331
+ #
332
+ def generate (launchitem=nil)
333
+
334
+ `#{@command}`.chomp
335
+ end
336
+
337
+ #
338
+ # Is a simple call to OpenWFE::split_wfid()
339
+ #
340
+ def split_wfid (wfid)
341
+
342
+ OpenWFE.split_wfid(wfid)
343
+ end
344
+
345
+ #
346
+ # This method is called by OpenWFE::split_wfid() when it has detected
347
+ # a wfid that is a UUID.
348
+ #
349
+ # Splits the first part of the uuid (will be used for the
350
+ # expression storage directory structure).
351
+ #
352
+ def self.split_wfid (wfid)
353
+
354
+ s = wfid[0, 8]
355
+ a = []
356
+ 4.times do |i|
357
+ a << s[i*2, 2]
358
+ end
359
+ a
360
+ end
361
+ end
362
+
363
+ #
364
+ # "module methods"
365
+ #
366
+
367
+ SPLIT_MAP = {
368
+ "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" => UuidWfidGenerator,
369
+ "[0-9]{8}-[a-z]*" => KotobaWfidGenerator
370
+ }
371
+
372
+ #
373
+ # This method should be able to split any wfid whose scheme is implemented
374
+ # here.
375
+ #
376
+ def OpenWFE.split_wfid (wfid)
377
+
378
+ SPLIT_MAP.each do |regex, clazz|
379
+ return clazz.split_wfid(wfid) if wfid.match(regex)
380
+ end
381
+ #
382
+ # else
383
+ #
384
+ DefaultWfidGenerator.split_wfid(wfid)
385
+ end
386
+
387
+ end
388
+
@@ -0,0 +1,224 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2006-2008, Nicolas Modryzk and 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
+ # Nicolas Modrzyk at openwfe.org
38
+ # John Mettraux at openwfe.org
39
+ #
40
+
41
+ require 'openwfe/utils'
42
+ require 'openwfe/storage/yamlcustom'
43
+ require 'openwfe/storage/yamlfilestorage'
44
+ require 'openwfe/expool/threadedexpstorage'
45
+
46
+ require 'openwfe/expressions/flowexpression'
47
+ #require 'openwfe/expressions/raw_xml'
48
+ #--
49
+ # making sure classes in those files are loaded
50
+ # before their yaml persistence is tuned
51
+ # (else the reopening of the class is interpreted as
52
+ # a definition of the class...)
53
+ #++
54
+
55
+
56
+ module OpenWFE
57
+
58
+ #
59
+ # YAML expression storage. Expressions (atomic pieces of process instances)
60
+ # are stored in a hierarchy of YAML files.
61
+ #
62
+ class YamlFileExpressionStorage < YamlFileStorage
63
+ include OwfeServiceLocator
64
+ include ExpressionStorageBase
65
+
66
+ def initialize (service_name, application_context)
67
+
68
+ super service_name, application_context, '/expool'
69
+
70
+ observe_expool
71
+ end
72
+
73
+ #
74
+ # Find expressions matching various criteria.
75
+ # (See Engine#list_process_status for an explanation)
76
+ #
77
+ def find_expressions (options)
78
+
79
+ wfid_prefix = options[:wfid_prefix]
80
+ wfid_regex = nil
81
+ wfid_regex = Regexp.new("^"+wfid_prefix) if wfid_prefix
82
+
83
+ options.delete :wfid_prefix
84
+ # no need to check this in further does_match? calls
85
+
86
+ result = []
87
+
88
+ each_object_path do |path|
89
+
90
+ unless path[-23..-1] == 'engine_environment.yaml'
91
+
92
+ a = self.class.split_file_path path
93
+
94
+ next unless a
95
+ # not an expression file
96
+
97
+ wfid = a[0]
98
+
99
+ next if wfid_regex and (not wfid_regex.match(wfid))
100
+ end
101
+
102
+ fexp = load_object path
103
+
104
+ next unless does_match?(options, fexp)
105
+
106
+ result << fexp
107
+ end
108
+
109
+ result
110
+ end
111
+
112
+ def fetch_root (wfid)
113
+
114
+ fei = FlowExpressionId.new
115
+ fei.wfid = wfid
116
+ fei.expid = "0"
117
+ fei.expression_name = "process-definition"
118
+
119
+ root = self[fei]
120
+
121
+ return root if root
122
+
123
+ #
124
+ # direct hit missed, scanning...
125
+
126
+ each_object_path(compute_dir_path(wfid)) do |p|
127
+
128
+ a = self.class.split_file_path p
129
+ next unless a
130
+
131
+ next unless a[0] == wfid
132
+
133
+ fexp = load_object p
134
+
135
+ return fexp if fexp.is_a?(DefineExpression)
136
+ end
137
+
138
+ nil
139
+ end
140
+
141
+ #
142
+ # Returns a human-readable list of the current YAML file paths.
143
+ # (one expression per path).
144
+ #
145
+ def to_s
146
+
147
+ s = "\n\n==== #{self.class} ===="
148
+ s << "\n"
149
+ each_object_path do |path|
150
+ s << path
151
+ s << "\n"
152
+ end
153
+ s << "==== . ====\n"
154
+ s
155
+ end
156
+
157
+ #
158
+ # Returns nil (if the path doesn't match an stored expression path)
159
+ # or an array [ workflow_instance_id, expression_id, expression_name ].
160
+ #
161
+ # This is a class method (not an instance one).
162
+ #
163
+ def self.split_file_path (path)
164
+
165
+ md = path.match %r{.*/(.*)__([\d.]*)_(.*).yaml}
166
+ return nil unless md
167
+ [ md[1], md[2], md[3] ]
168
+ end
169
+
170
+ protected
171
+
172
+ def compute_dir_path (wfid)
173
+
174
+ wfid = FlowExpressionId.to_parent_wfid wfid
175
+
176
+ a_wfid = get_wfid_generator.split_wfid wfid
177
+
178
+ @basepath + a_wfid[-2] + "/" + a_wfid[-1] + "/"
179
+ end
180
+
181
+ def compute_file_path (fei)
182
+
183
+ return @basepath + "/engine_environment.yaml" \
184
+ if fei.workflow_instance_id == "0"
185
+
186
+ wfid = fei.parent_workflow_instance_id
187
+
188
+ compute_dir_path(wfid) +
189
+ fei.workflow_instance_id + "__" +
190
+ fei.expression_id + "_" +
191
+ fei.expression_name + ".yaml"
192
+ end
193
+
194
+ #--
195
+ # Returns true if the path points to a file containing an
196
+ # expression whose name is in the list of expression names
197
+ # corresponding to the given kind (class) of expressions.
198
+ #
199
+ #def matches (path, kind)
200
+ # exp_names = get_expression_map.get_expression_names(kind)
201
+ # exp_names.each do |exp_name|
202
+ # return true \
203
+ # if OpenWFE::ends_with(path, "_#{exp_name}.yaml")
204
+ # end
205
+ # false
206
+ #end
207
+ #++
208
+ end
209
+
210
+ #
211
+ # With this extension of YmalFileExpressionStorage, persistence occurs
212
+ # in a separate thread, for a snappier response.
213
+ #
214
+ class ThreadedYamlFileExpressionStorage < YamlFileExpressionStorage
215
+ include ThreadedStorageMixin
216
+
217
+ def initialize (service_name, application_context)
218
+
219
+ super
220
+
221
+ start_queue
222
+ end
223
+ end
224
+ end