openwferu 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/examples/mano_tracker.rb +13 -6
  2. data/examples/quotereporter.rb +3 -2
  3. data/lib/openwfe/engine/engine.rb +31 -4
  4. data/lib/openwfe/engine/file_persisted_engine.rb +35 -9
  5. data/lib/openwfe/expool/expressionpool.rb +116 -67
  6. data/lib/openwfe/expool/expstorage.rb +142 -101
  7. data/lib/openwfe/expool/history.rb +7 -2
  8. data/lib/openwfe/expool/yamlexpstorage.rb +150 -6
  9. data/lib/openwfe/expressions/{fe_condition.rb → condition.rb} +4 -6
  10. data/lib/openwfe/expressions/expressionmap.rb +8 -0
  11. data/lib/openwfe/expressions/fe_cancel.rb +109 -0
  12. data/lib/openwfe/expressions/fe_concurrence.rb +252 -16
  13. data/lib/openwfe/expressions/fe_cursor.rb +8 -3
  14. data/lib/openwfe/{util/stoppable.rb → expressions/fe_do.rb} +42 -11
  15. data/lib/openwfe/expressions/fe_iterator.rb +4 -3
  16. data/lib/openwfe/expressions/fe_misc.rb +3 -2
  17. data/lib/openwfe/expressions/fe_participant.rb +5 -0
  18. data/lib/openwfe/expressions/fe_raw.rb +10 -2
  19. data/lib/openwfe/expressions/fe_subprocess.rb +1 -1
  20. data/lib/openwfe/expressions/fe_time.rb +43 -23
  21. data/lib/openwfe/expressions/fe_value.rb +1 -1
  22. data/lib/openwfe/expressions/flowexpression.rb +22 -22
  23. data/lib/openwfe/expressions/raw_prog.rb +20 -39
  24. data/lib/openwfe/expressions/raw_xml.rb +6 -6
  25. data/lib/openwfe/expressions/timeout.rb +8 -3
  26. data/lib/openwfe/expressions/wtemplate.rb +67 -0
  27. data/lib/openwfe/flowexpressionid.rb +4 -1
  28. data/lib/openwfe/participants/atomparticipants.rb +13 -1
  29. data/lib/openwfe/participants/enoparticipant.rb +66 -5
  30. data/lib/openwfe/participants/participantmap.rb +12 -0
  31. data/lib/openwfe/rudefinitions.rb +15 -3
  32. data/lib/openwfe/service.rb +4 -5
  33. data/lib/openwfe/storage/yamlfilestorage.rb +72 -45
  34. data/lib/openwfe/util/dollar.rb +17 -4
  35. data/lib/openwfe/util/lru.rb +154 -0
  36. data/lib/openwfe/util/otime.rb +26 -5
  37. data/lib/openwfe/util/scheduler.rb +44 -36
  38. data/lib/openwfe/util/schedulers.rb +4 -2
  39. data/lib/openwfe/utils.rb +62 -0
  40. data/lib/openwfe/version.rb +1 -1
  41. data/lib/openwfe/worklist/storeparticipant.rb +34 -5
  42. data/test/eno_test.rb +69 -0
  43. data/test/file_persistence_test.rb +13 -11
  44. data/test/flowtestbase.rb +29 -15
  45. data/test/ft_0.rb +2 -1
  46. data/test/ft_0b_sequence.rb +2 -1
  47. data/test/ft_0c_testname.rb +6 -5
  48. data/test/ft_0d_participant.rb +2 -1
  49. data/test/ft_10_loop.rb +11 -6
  50. data/test/ft_10b_loop2.rb +63 -0
  51. data/test/ft_11_ppd.rb +39 -13
  52. data/test/ft_12_blockparticipant.rb +2 -1
  53. data/test/ft_13_eno.rb +3 -2
  54. data/test/ft_14_subprocess.rb +2 -1
  55. data/test/ft_14b_subprocess.rb +2 -1
  56. data/test/ft_15_iterator.rb +2 -1
  57. data/test/ft_16_fqv.rb +2 -1
  58. data/test/ft_17_condition.rb +2 -1
  59. data/test/ft_18_pname.rb +2 -1
  60. data/test/ft_19_csv.rb +2 -1
  61. data/test/ft_1_unset.rb +14 -18
  62. data/test/ft_1b_unset.rb +39 -0
  63. data/test/ft_20_cron.rb +2 -1
  64. data/test/ft_21_cron.rb +2 -1
  65. data/test/ft_22_history.rb +7 -5
  66. data/test/ft_23_when.rb +2 -1
  67. data/test/ft_23b_when.rb +2 -1
  68. data/test/ft_24_def.rb +2 -1
  69. data/test/ft_25_cancel.rb +79 -0
  70. data/test/ft_26_load.rb +197 -0
  71. data/test/ft_2_concurrence.rb +89 -15
  72. data/test/ft_2b_concurrence.rb +152 -0
  73. data/test/ft_2c_concurrence.rb +39 -0
  74. data/test/ft_3_equals.rb +4 -3
  75. data/test/ft_4_misc.rb +4 -3
  76. data/test/ft_5_time.rb +2 -1
  77. data/test/ft_6_lambda.rb +2 -1
  78. data/test/ft_7_lose.rb +53 -17
  79. data/test/ft_8_forget.rb +7 -6
  80. data/test/ft_9_cursor.rb +8 -7
  81. data/test/hparticipant_test.rb +37 -14
  82. data/test/lru_test.rb +79 -0
  83. data/test/misc_test.rb +16 -0
  84. data/test/rake_qtest.rb +7 -0
  85. data/test/raw_prog_test.rb +0 -13
  86. data/test/rutest_utils.rb +15 -2
  87. data/test/scheduler_test.rb +31 -4
  88. data/test/timeout_test.rb +6 -2
  89. data/test/wfid_test.rb +68 -0
  90. metadata +169 -158
  91. data/lib/openwfe/expool/journalexpstorage.rb +0 -312
  92. data/lib/openwfe/util/lru_cache.rb +0 -149
@@ -41,9 +41,9 @@
41
41
 
42
42
  require 'openwfe/workitem'
43
43
  require 'openwfe/flowexpressionid'
44
+ require 'openwfe/expressions/condition'
44
45
  require 'openwfe/expressions/flowexpression'
45
46
  require 'openwfe/expressions/fe_utils'
46
- require 'openwfe/expressions/fe_condition'
47
47
 
48
48
 
49
49
  #
@@ -162,7 +162,7 @@ module OpenWFE
162
162
  def store_itself ()
163
163
  ldebug { "store_itself() for #{@fei.to_debug_s}" }
164
164
  #ldebug { "store_itself() \n#{OpenWFE::caller_to_s(0, 6)}" }
165
- get_expression_pool().update(self)
165
+ return get_expression_pool().update(self)
166
166
  end
167
167
 
168
168
  #
@@ -222,7 +222,7 @@ module OpenWFE
222
222
  # or by // to indicate engine level (global) scope.
223
223
  #
224
224
  def lookup_variable (varname)
225
- return get_environment()[varname]
225
+ get_environment()[varname]
226
226
  end
227
227
 
228
228
  #
@@ -307,6 +307,21 @@ module OpenWFE
307
307
  return result
308
308
  end
309
309
 
310
+ #
311
+ # For an expression like
312
+ #
313
+ # iterator :on_value => "a, b, c", to-variable => "v0" do
314
+ # # ...
315
+ # end
316
+ #
317
+ # this call
318
+ #
319
+ # lookup_comma_list_attribute(:on_value, wi)
320
+ #
321
+ # will return
322
+ #
323
+ # [ 'a', 'b', 'c' ]
324
+ #
310
325
  def lookup_comma_list_attribute (attname, workitem, default=nil)
311
326
 
312
327
  a = lookup_attribute(attname, workitem, default)
@@ -344,7 +359,7 @@ module OpenWFE
344
359
 
345
360
  ldebug { "new_environment() is #{env.fei.to_debug_s}" }
346
361
 
347
- env.store_itself()
362
+ return env.store_itself()
348
363
  end
349
364
 
350
365
  #
@@ -377,9 +392,13 @@ module OpenWFE
377
392
  #
378
393
  def synchronize
379
394
 
395
+ #ldebug { "synchronize() ---in--- for #{@fei.to_debug_s}" }
396
+
380
397
  get_expression_pool.get_monitor(@fei).synchronize do
381
398
  yield
382
399
  end
400
+
401
+ #ldebug { "synchronize() --out-- for #{@fei.to_debug_s}" }
383
402
  end
384
403
 
385
404
  #
@@ -420,24 +439,5 @@ module OpenWFE
420
439
  end
421
440
  end
422
441
 
423
- #
424
- # A parent class for CursorExpression and IteratorExpression.
425
- # Takes care of removing templates before replying to the parent
426
- # expression.
427
- #
428
- class WithTemplateExpression < FlowExpression
429
-
430
- #
431
- # this overriden method takes care of removing all the children
432
- # (templates) before replying to its parent.
433
- #
434
- def reply_to_parent (workitem)
435
- @children.each do |child|
436
- get_expression_pool.remove(child)
437
- end
438
- super(workitem)
439
- end
440
- end
441
-
442
442
  end
443
443
 
@@ -175,51 +175,32 @@ module OpenWFE
175
175
  #
176
176
  class ProcessDefinition
177
177
 
178
- def initialize (exp_names=nil)
178
+ #def initialize (exp_names=nil)
179
+ def initialize ()
179
180
 
180
181
  super()
181
182
 
182
- if not exp_names
183
- exp_names = $EXPRESSION_NAMES if $EXPRESSION_NAMES
184
- else
185
- if exp_names.kind_of? ExpressionMap
186
- exp_names = exp_names.expression_names
187
- elsif exp_names.kind_of? Engine
188
- exp_names = exp_names.get_expression_map.expression_names
189
- elsif exp_names.kind_of? Hash
190
- exp_names = exp_names[S_EXPRESSION_MAP].expression_names
191
- elsif not exp_names.kind_of? Array
192
- exp_names = $EXPRESSION_NAMES
193
- end
194
- end
195
-
196
- if not exp_names
197
- raise "no expression names found, please provide them"
198
- end
199
-
200
- @exp_names = exp_names
201
-
202
- #exp_names.each do |exp_name|
203
- # register_expression(exp_name)
183
+ #if not exp_names
184
+ # exp_names = $EXPRESSION_NAMES if $EXPRESSION_NAMES
185
+ #else
186
+ # if exp_names.kind_of? ExpressionMap
187
+ # exp_names = exp_names.expression_names
188
+ # elsif exp_names.kind_of? Engine
189
+ # exp_names = exp_names.get_expression_map.expression_names
190
+ # elsif exp_names.kind_of? Hash
191
+ # exp_names = exp_names[S_EXPRESSION_MAP].expression_names
192
+ # elsif not exp_names.kind_of? Array
193
+ # exp_names = $EXPRESSION_NAMES
194
+ # end
204
195
  #end
196
+ #if not exp_names
197
+ # raise "no expression names found, please provide them"
198
+ #end
199
+ #@exp_names = exp_names
205
200
 
206
201
  @previous_parent_expression = []
207
202
  end
208
203
 
209
- #
210
- # previous trick
211
- #
212
- # kept for the record.
213
- #
214
- #def register_expression (expression_name)
215
- # _exp_name = OpenWFE.make_safe(exp_name)
216
- # self.instance_eval """
217
- # def #{_exp_name} (params={}, &block)
218
- # make_expression('#{exp_name}', params, &block)
219
- # end
220
- # """
221
- #end
222
-
223
204
  def method_missing (m, *args, &block)
224
205
 
225
206
  methodname = m.to_s
@@ -298,8 +279,8 @@ module OpenWFE
298
279
  # A class method for actually "making" the process
299
280
  # segment raw representation
300
281
  #
301
- def ProcessDefinition.do_make (exp_names=nil)
302
- self.new(exp_names).make
282
+ def ProcessDefinition.do_make ()
283
+ self.new().make
303
284
  end
304
285
  end
305
286
 
@@ -66,13 +66,13 @@ module OpenWFE
66
66
  end
67
67
 
68
68
  def raw_representation
69
- synchronize do
70
- if not @raw_representation
71
- @raw_representation = \
72
- REXML::Document.new(@raw_representation_s).root
73
- end
74
- return @raw_representation
69
+ #synchronize do
70
+ if not @raw_representation
71
+ @raw_representation = \
72
+ REXML::Document.new(@raw_representation_s).root
75
73
  end
74
+ return @raw_representation
75
+ #end
76
76
  end
77
77
 
78
78
  protected
@@ -73,9 +73,6 @@ module OpenWFE
73
73
  @timeout_at = Time.new.to_f + timeout
74
74
  end
75
75
 
76
- #
77
- # Overrides the parent method to make sure a potential
78
- #
79
76
  def reschedule (scheduler)
80
77
  to_reschedule(scheduler)
81
78
  end
@@ -89,6 +86,14 @@ module OpenWFE
89
86
  super(workitem)
90
87
  end
91
88
 
89
+ def set_timedout_flag (workitem)
90
+ workitem.attributes["__timed_out__"] = "true"
91
+ end
92
+
93
+ def remove_timedout_flag (workitem)
94
+ workitem.attributes.delete("__timed_out__")
95
+ end
96
+
92
97
  protected
93
98
 
94
99
  #
@@ -0,0 +1,67 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2006-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
+ # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
+ #
35
+
36
+ #
37
+ # "made in Japan"
38
+ #
39
+ # John Mettraux at openwfe.org
40
+ #
41
+
42
+ require 'openwfe/expressions/flowexpression'
43
+
44
+
45
+ module OpenWFE
46
+
47
+ #
48
+ # A parent class for CursorExpression and IteratorExpression.
49
+ # Takes care of removing templates before replying to the parent
50
+ # expression.
51
+ #
52
+ class WithTemplateExpression < FlowExpression
53
+
54
+ #
55
+ # this overriden method takes care of removing all the children
56
+ # (templates) before replying to its parent.
57
+ #
58
+ def reply_to_parent (workitem)
59
+ @children.each do |child|
60
+ get_expression_pool.remove(child)
61
+ end
62
+ super(workitem)
63
+ end
64
+ end
65
+
66
+ end
67
+
@@ -96,10 +96,13 @@ module OpenWFE
96
96
 
97
97
  alias eql? ==
98
98
 
99
- alias to_debug_s to_s
99
+ #alias to_debug_s to_s
100
100
  #def to_debug_s
101
101
  # "#{to_s} (h#{hash}) (i#{object_id})"
102
102
  #end
103
+ def to_debug_s
104
+ "(fei #{@workflow_definition_name} #{@workflow_definition_revision} #{@workflow_instance_id} #{@expression_id} #{@expression_name})"
105
+ end
103
106
 
104
107
  #
105
108
  # Returns the workflow instance id without any subflow indices.
@@ -70,6 +70,12 @@ module OpenWFE
70
70
  # </p>
71
71
  # """) # the template for each entry
72
72
  #
73
+ # The 'template' parameter may contain an instance of File instead of
74
+ # an instance of String.
75
+ #
76
+ # feed0 = AtomParticipant.new(
77
+ # 20, File.new("path/to/my/atom/template.txt")
78
+ #
73
79
  # The template can be passed as the second parameter (after the max entry
74
80
  # count) or as a block :
75
81
  #
@@ -144,8 +150,14 @@ module OpenWFE
144
150
 
145
151
  template = if @block_template
146
152
  @block_template.call(fe, self, workitem)
153
+ elsif @template
154
+ if @template.kind_of? File
155
+ @template.readlines
156
+ else
157
+ @template.to_s
158
+ end
147
159
  else
148
- @template
160
+ "(no template given)"
149
161
  end
150
162
 
151
163
  return OpenWFE::dosub(template, fe, workitem)
@@ -74,13 +74,44 @@ module OpenWFE
74
74
  # "Monsieur Toto"
75
75
  # end
76
76
  # participant :ref => 'eno'
77
- # print "ok"
78
77
  # end
79
78
  # end
80
79
  # end
81
80
  # end
82
81
  #
83
- # TODO #8426 : use a block to define template
82
+ # The 'template' parameter may contain an instance of File instead of
83
+ # an instance of String.
84
+ #
85
+ # @engine.register_participant(
86
+ # 'eno',
87
+ # EmailNotificationParticipant.new(
88
+ # "googlemail.l.google.com",
89
+ # 25,
90
+ # "eno@outoftheblue.co.jp",
91
+ # File.new("path/to/my/mail/template.txt")))
92
+ #
93
+ # You can also define the email template as a ruby block :
94
+ #
95
+ # p = EmailNotificationParticipant.new("googlemail.l.google.com", 25, "eno@co.co.jp") do | flowexpression, participant, workitem |
96
+ #
97
+ # # generally, only the workitem is used within a template
98
+ #
99
+ # s = ""
100
+ #
101
+ # # the header of the message
102
+ #
103
+ # s << "Subject: #{workitem.subject}\n\n"
104
+ #
105
+ # # then, the body
106
+ #
107
+ # workitem.attributes.each do |key, value|
108
+ # s << "- '#{k}' => '#{value}'\n"
109
+ # end
110
+ # s << "\ndone.\n"
111
+ # end
112
+ #
113
+ # Note that the template integrates the subject and requires then a double
114
+ # newline before the message body.
84
115
  #
85
116
  class EmailNotificationParticipant
86
117
  include LocalParticipant
@@ -89,24 +120,54 @@ module OpenWFE
89
120
  # Create a new email notification participant. Requires
90
121
  # a mail server, port, a from address, and a mail message template
91
122
  #
92
- def initialize (smtp_server, smtp_port, from_address, template)
123
+ def initialize (
124
+ smtp_server, smtp_port, from_address, template=nil, &block)
125
+
93
126
  @smtp_server = smtp_server
94
127
  @smtp_port = smtp_port
95
128
  @from_address = from_address
96
129
  @template = template
130
+
131
+ @block_template = block
97
132
  end
98
133
 
134
+ #
135
+ # The method called each time a workitem reaches this participant
136
+ #
99
137
  def consume (workitem)
138
+
100
139
  fe = get_flow_expression(workitem)
101
140
  to_address = workitem.email_target
141
+
142
+ #
102
143
  # 1. Expand variables
103
- msg = OpenWFE::dosub(@template, fe, workitem)
144
+
145
+ msg = if @block_template
146
+ @block_template.call(fe, self, workitem)
147
+ elsif @template
148
+ template = if @template.kind_of? File
149
+ @template.readlines
150
+ else
151
+ @template.to_s
152
+ end
153
+ OpenWFE::dosub(template, fe, workitem)
154
+ else
155
+ "(no template given)"
156
+ end
157
+
158
+ puts "msg >>>\n#{msg}<<<"
159
+
160
+ #
104
161
  # 2. Send message
162
+
105
163
  Net::SMTP.start(@smtp_server, @smtp_port) do |smtp|
106
164
  smtp.send_message(msg, @from_address, to_address)
107
165
  end
166
+
167
+ #
108
168
  # 3. Reply to engine
109
- reply_to_engine(workitem)
169
+
170
+ reply_to_engine(workitem)
110
171
  end
111
172
 
112
173
  end
@@ -67,6 +67,8 @@ module OpenWFE
67
67
  # This method is called by the engine's own register_participant()
68
68
  # method.
69
69
  #
70
+ # The participant instance is returned by this method call
71
+ #
70
72
  def register_participant (regex, participant=nil, &block)
71
73
 
72
74
  if not participant
@@ -77,12 +79,22 @@ module OpenWFE
77
79
  participant = BlockParticipant.new(block)
78
80
  end
79
81
 
82
+ if participant.kind_of? Class
83
+ begin
84
+ participant = participant.new(regex, @application_context)
85
+ rescue
86
+ participant = participant.new
87
+ end
88
+ end
89
+
80
90
  regex = Regexp.new(regex.to_s) unless regex.kind_of? Regexp
81
91
 
82
92
  participant.application_context = @application_context \
83
93
  if participant.respond_to? :application_context=
84
94
 
85
95
  @participants << [ regex, participant ]
96
+
97
+ return participant
86
98
  end
87
99
 
88
100
  #
@@ -37,14 +37,12 @@
37
37
  # "made in Japan"
38
38
  #
39
39
 
40
+ require 'openwfe/utils'
40
41
  require 'openwfe/version'
41
42
 
42
43
 
43
44
  module OpenWFE
44
45
 
45
- #OPENWFE_VERSION = '1.7.2pre17'
46
- #OPENWFE_VERSION = '0.9.4'
47
-
48
46
  #
49
47
  # service names
50
48
 
@@ -77,6 +75,7 @@ module OpenWFE
77
75
  # (assumes the presence of an application context instance var)
78
76
  #
79
77
  module OwfeServiceLocator
78
+
80
79
  def get_engine
81
80
  return @application_context[S_ENGINE]
82
81
  end
@@ -95,6 +94,19 @@ module OpenWFE
95
94
  def get_participant_map
96
95
  return @application_context[S_PARTICIPANT_MAP]
97
96
  end
97
+
98
+ #
99
+ # Returns all the expression storage in the application context
100
+ # (there is usually a cache and a persisted exp storage).
101
+ #
102
+ def get_expression_storages
103
+ result = []
104
+ @application_context.each do |k, v|
105
+ result << v \
106
+ if OpenWFE::starts_with(k.to_s, S_EXPRESSION_STORAGE)
107
+ end
108
+ return result
109
+ end
98
110
  end
99
111
 
100
112
  end
@@ -76,11 +76,10 @@ module OpenWFE
76
76
 
77
77
  end
78
78
 
79
- def register (service)
80
-
81
- service.application_context[service.service_name] = service
82
- return service
83
- end
79
+ #def register (service)
80
+ # service.application_context[service.service_name] = service
81
+ # return service
82
+ #end
84
83
 
85
84
  end
86
85