openwferu 0.9.2 → 0.9.3

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 (63) hide show
  1. data/examples/mano_tracker.rb +165 -0
  2. data/examples/scheduler_cron_usage.rb +46 -0
  3. data/examples/scheduler_usage.rb +54 -0
  4. data/lib/openwfe/contextual.rb +7 -1
  5. data/lib/openwfe/engine/engine.rb +58 -15
  6. data/lib/openwfe/expool/expressionpool.rb +116 -14
  7. data/lib/openwfe/expool/expstorage.rb +12 -12
  8. data/lib/openwfe/expool/journalexpstorage.rb +1 -1
  9. data/lib/openwfe/expool/yamlexpstorage.rb +58 -22
  10. data/lib/openwfe/expressions/environment.rb +32 -2
  11. data/lib/openwfe/expressions/expressionmap.rb +17 -0
  12. data/lib/openwfe/expressions/fe_condition.rb +122 -0
  13. data/lib/openwfe/expressions/fe_cursor.rb +14 -5
  14. data/lib/openwfe/expressions/fe_participant.rb +55 -4
  15. data/lib/openwfe/expressions/fe_raw.rb +43 -12
  16. data/lib/openwfe/expressions/fe_subprocess.rb +10 -0
  17. data/lib/openwfe/expressions/fe_time.rb +117 -22
  18. data/lib/openwfe/expressions/fe_value.rb +27 -8
  19. data/lib/openwfe/expressions/flowexpression.rb +13 -6
  20. data/lib/openwfe/expressions/raw_prog.rb +13 -11
  21. data/lib/openwfe/expressions/timeout.rb +94 -0
  22. data/lib/openwfe/flowexpressionid.rb +17 -19
  23. data/lib/openwfe/logging.rb +35 -16
  24. data/lib/openwfe/participants/atomparticipants.rb +31 -7
  25. data/lib/openwfe/participants/enoparticipant.rb +43 -3
  26. data/lib/openwfe/participants/participant.rb +21 -1
  27. data/lib/openwfe/participants/participantmap.rb +4 -2
  28. data/lib/openwfe/participants/participants.rb +12 -17
  29. data/lib/openwfe/participants/soapparticipants.rb +15 -3
  30. data/lib/openwfe/rudefinitions.rb +3 -0
  31. data/lib/openwfe/service.rb +8 -0
  32. data/lib/openwfe/storage/yamlfilestorage.rb +85 -47
  33. data/lib/openwfe/{otime.rb → util/otime.rb} +0 -0
  34. data/lib/openwfe/util/scheduler.rb +415 -231
  35. data/lib/openwfe/util/schedulers.rb +11 -3
  36. data/lib/openwfe/util/stoppable.rb +69 -0
  37. data/lib/openwfe/utils.rb +14 -25
  38. data/lib/openwfe/workitem.rb +12 -6
  39. data/lib/openwfe/worklist/storeparticipant.rb +145 -0
  40. data/test/{atomtest.rb → atom_test.rb} +0 -0
  41. data/test/{crontest.rb → cron_test.rb} +7 -6
  42. data/test/cronline_test.rb +51 -0
  43. data/test/{dollartest.rb → dollar_test.rb} +0 -0
  44. data/test/{feitest.rb → fei_test.rb} +0 -0
  45. data/test/file_persistence_test.rb +15 -9
  46. data/test/flowtestbase.rb +11 -5
  47. data/test/ft_0.rb +8 -0
  48. data/test/ft_10_loop.rb +72 -10
  49. data/test/ft_11_ppd.rb +49 -0
  50. data/test/ft_17_condition.rb +83 -0
  51. data/test/ft_18_pname.rb +59 -0
  52. data/test/hparticipant_test.rb +96 -0
  53. data/test/{misctest.rb → misc_test.rb} +1 -1
  54. data/test/rake_qtest.rb +10 -4
  55. data/test/rake_test.rb +12 -1
  56. data/test/raw_prog_test.rb +1 -1
  57. data/test/restart_cron_test.rb +78 -0
  58. data/test/restart_test.rb +79 -0
  59. data/test/scheduler_test.rb +92 -0
  60. data/test/{timetest.rb → time_test.rb} +3 -38
  61. data/test/timeout_test.rb +73 -0
  62. metadata +26 -11
  63. data/lib/openwfe/worklist/worklists.rb +0 -175
@@ -0,0 +1,94 @@
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
+ # $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/util/otime'
43
+ require 'openwfe/util/scheduler'
44
+
45
+
46
+ #
47
+ # Managing timeout for expressions like 'participant' and 'when'
48
+ #
49
+
50
+ module OpenWFE
51
+
52
+
53
+ #
54
+ # The timeout behaviour is implemented here, making it easy
55
+ # to mix it in into ParticipantExpression and WhenExpression.
56
+ #
57
+ module TimeoutMixin
58
+ include Schedulable
59
+
60
+ attr_accessor \
61
+ :timeout_at,
62
+ :scheduler_job_id
63
+
64
+ def determine_timeout
65
+
66
+ timeout = lookup_attribute(:timeout, @applied_workitem)
67
+ return unless timeout
68
+
69
+ timeout = OpenWFE::parse_time_string(timeout)
70
+ @timeout_at = Time.new.to_f + timeout
71
+
72
+ reschedule(get_scheduler)
73
+ end
74
+
75
+ def reschedule (scheduler)
76
+
77
+ return unless @timeout_at
78
+
79
+ @scheduler_job_id =
80
+ scheduler.schedule_at(@timeout_at, self, nil)
81
+
82
+ ldebug do
83
+ "reschedule() will timeout at "+
84
+ "#{OpenWFE::to_iso8601_date(@timeout_at)}"
85
+ end
86
+
87
+ #store_itself()
88
+ #
89
+ # done in the including expression
90
+ end
91
+ end
92
+
93
+ end
94
+
@@ -49,16 +49,22 @@ module OpenWFE
49
49
  class FlowExpressionId
50
50
 
51
51
  attr_accessor \
52
- :owfe_version, \
53
- :engine_id, \
54
- :initial_engine_id, \
55
- :workflow_definition_url, \
56
- :workflow_definition_name, \
57
- :workflow_definition_revision, \
58
- :workflow_instance_id, \
59
- :expression_name, \
52
+ :owfe_version,
53
+ :engine_id,
54
+ :initial_engine_id,
55
+ :workflow_definition_url,
56
+ :workflow_definition_name,
57
+ :workflow_definition_revision,
58
+ :workflow_instance_id,
59
+ :expression_name,
60
60
  :expression_id
61
61
 
62
+ #
63
+ # A shortcut for fei.workflow_instance_id.
64
+ # There's also fei.parent_wfid.
65
+ #
66
+ alias :wfid :workflow_instance_id
67
+
62
68
  #
63
69
  # overrides the classical to_s()
64
70
  #
@@ -85,17 +91,7 @@ module OpenWFE
85
91
  end
86
92
 
87
93
  def dup
88
- n = FlowExpressionId.new
89
- n.owfe_version = @owfe_version.dup
90
- n.engine_id = @engine_id.dup
91
- n.initial_engine_id = @initial_engine_id.dup
92
- n.workflow_definition_url = @workflow_definition_url.dup
93
- n.workflow_definition_name = @workflow_definition_name.dup
94
- n.workflow_definition_revision = @workflow_definition_revision.dup
95
- n.workflow_instance_id = @workflow_instance_id.dup
96
- n.expression_name = @expression_name.dup
97
- n.expression_id = @expression_id.dup
98
- return n
94
+ OpenWFE::fulldup(self)
99
95
  end
100
96
 
101
97
  alias eql? ==
@@ -117,6 +113,8 @@ module OpenWFE
117
113
  return workflow_instance_id[0..i-1]
118
114
  end
119
115
 
116
+ alias :parent_wfid :parent_workflow_instance_id
117
+
120
118
  #
121
119
  # This class method parses a string into a FlowExpressionId instance
122
120
  #
@@ -50,34 +50,53 @@ module OpenWFE
50
50
  #
51
51
  module Logging
52
52
 
53
- def init_default_logging (filename)
54
- log = Logger.new(filename)
55
- @application_context[S_LOGGER] = log
53
+ def ldebug (message=nil, &block)
54
+ do_log(:debug, message, &block)
56
55
  end
57
56
 
58
- def ldebug (&block)
59
- log = get_logger
60
- log.debug(who(), &block) if log
57
+ def linfo (message=nil, &block)
58
+ do_log(:info, message, &block)
61
59
  end
62
60
 
63
- def linfo (&block)
64
- log = get_logger
65
- log.info(who(), &block) if log
61
+ def lwarn (message=nil, &block)
62
+ do_log(:warn, message, &block)
66
63
  end
67
64
 
68
- def lwarn (&block)
69
- log = get_logger
70
- log.warn(who(), &block) if log
65
+ def lerror (message=nil, &block)
66
+ do_log(:error, message, &block)
67
+ end
68
+
69
+ def lfatal (message=nil, &block)
70
+ do_log(:fatal, message, &block)
71
+ end
72
+
73
+ def lunknown (message=nil, &block)
74
+ do_log(:unknown, message, &block)
71
75
  end
72
76
 
73
77
  private
74
78
 
75
- def get_logger
76
- return @application_context[S_LOGGER] if @application_context
77
- return Logger.new(STDOUT)
79
+ def do_log (level, message, &block)
80
+
81
+ return unless $OWFE_LOG
82
+
83
+ logblock = lambda do
84
+ if block
85
+ "#{log_prepare(message)} - #{block.call}"
86
+ else
87
+ "#{log_prepare(message)}"
88
+ end
89
+ end
90
+
91
+ $OWFE_LOG.send level, &logblock
92
+ end
93
+
94
+ def log_prepare (message)
95
+ return log_author() if not message
96
+ return "#{log_author} - #{message}"
78
97
  end
79
98
 
80
- def who
99
+ def log_author
81
100
  if respond_to? :service_name
82
101
  "#{self.class} '#{self.service_name}'"
83
102
  else
@@ -52,7 +52,7 @@ require 'monitor'
52
52
  require 'rubygems'
53
53
  require 'atom/collection'
54
54
 
55
- require 'openwfe/participants/participants'
55
+ require 'openwfe/participants/participant'
56
56
 
57
57
 
58
58
  module OpenWFE
@@ -61,18 +61,42 @@ module OpenWFE
61
61
  # Stores the incoming workitem into an 'atom feed'
62
62
  #
63
63
  # An example :
64
- # <tt>
64
+ #
65
65
  # feed0 = AtomParticipant.new(
66
- # 20,
66
+ # 20, # no more than 20 entries are kept
67
67
  # """
68
68
  # <p>
69
69
  # <h1>${f:colour}</h1>
70
70
  # </p>
71
- # """)
72
- # </tt>
71
+ # """) # the template for each entry
72
+ #
73
+ # The template can be passed as the second parameter (after the max entry
74
+ # count) or as a block :
75
+ #
76
+ # feed1 = AtomParticipant.new(20) do |flow_expression, atom_participant, workitem|
77
+ # #
78
+ # # usually only the workitem parameter is used
79
+ # # but the other two allow for advanced tricks...
80
+ #
81
+ # atom_participant.content_type = "xml"
82
+ # # by default, it's "xhtml"
83
+ #
84
+ # s = "<task>"
85
+ # s << "<name>#{workitem.task_name}</name>"
86
+ # s << "<assignee>#{workitem.task_assignee}</assignee>"
87
+ # s << "<duedate>#{workitem.task_duedate}</duedate>"
88
+ # s << "</task>"
89
+ #
90
+ # # the block is supposed to 'return' a string which is the
91
+ # # effective template
92
+ # end
93
+ #
94
+ # This participant uses
95
+ # "atom-tools" from http://code.necronomicorp.com/trac/atom-tools
96
+ #
73
97
  #
74
- class AtomParticipant < LocalParticipant
75
- include MonitorMixin
98
+ class AtomParticipant
99
+ include LocalParticipant, MonitorMixin
76
100
 
77
101
  attr_accessor \
78
102
  :content_type # blocks may manipulate them
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2007, Alain Hoang, OpenWFE.org
3
+ # Copyright (c) 2007, Alain Hoang and John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -36,19 +36,59 @@
36
36
  # "made in Japan"
37
37
  #
38
38
  # Alain Hoang at openwfe.org
39
+ # John Mettraux at openwfe.org
39
40
  #
40
41
 
41
42
  require 'net/smtp'
42
43
 
43
- module OpenWFE
44
+ require 'openwfe/participants/participant'
45
+
44
46
 
47
+ module OpenWFE
45
48
 
46
49
  #
47
50
  # This participant is used to send an email notification
48
- class EmailNotificationParticipant < LocalParticipant
51
+ #
52
+ # @engine.register_participant(
53
+ # 'eno',
54
+ # EmailNotificationParticipant.new(
55
+ # "googlemail.l.google.com",
56
+ # 25,
57
+ # "eno@outoftheblue.co.jp",
58
+ # """Subject: test 0
59
+ #
60
+ # 0 : ${r:Time.new}
61
+ # 1 : ${f:customer_name}
62
+ # """))
63
+ #
64
+ # And then, from the process definition :
65
+ #
66
+ # class TestDefinition0 < OpenWFE::ProcessDefinition
67
+ # def make
68
+ # process_definition :name => "test0", :revision => "0" do
69
+ # sequence do
70
+ # set :field => 'email_target' do
71
+ # "whatever56x56@gmail.com"
72
+ # end
73
+ # set :field => 'customer_name' do
74
+ # "Monsieur Toto"
75
+ # end
76
+ # participant :ref => 'eno'
77
+ # print "ok"
78
+ # end
79
+ # end
80
+ # end
81
+ # end
82
+ #
83
+ # TODO #8426 : use a block to define template
84
+ #
85
+ class EmailNotificationParticipant
86
+ include LocalParticipant
49
87
 
88
+ #
50
89
  # Create a new email notification participant. Requires
51
90
  # a mail server, port, a from address, and a mail message template
91
+ #
52
92
  def initialize (smtp_server, smtp_port, from_address, template)
53
93
  @smtp_server = smtp_server
54
94
  @smtp_port = smtp_port
@@ -50,7 +50,6 @@ module OpenWFE
50
50
  # other pieces of code may easily 'mix it in'.
51
51
  #
52
52
  module Participant
53
- include Contextual
54
53
 
55
54
  #
56
55
  # A participant will be receiving workitems via this method.
@@ -59,6 +58,10 @@ module OpenWFE
59
58
  # items will be fed to this cancel() and not to consume().
60
59
  #
61
60
  def consume (workitem)
61
+
62
+ raise NotImplementedError.new(
63
+ "implementation for method consume() "+
64
+ "is missing in class '#{self.class}'")
62
65
  end
63
66
 
64
67
  #
@@ -66,6 +69,14 @@ module OpenWFE
66
69
  #
67
70
  #def cancel (cancelitem)
68
71
  #end
72
+ end
73
+
74
+ #
75
+ # Local participants provide handy methods like reply_to_engine() to
76
+ # further implementations of the Participant concept.
77
+ #
78
+ module LocalParticipant
79
+ include Participant, Contextual, Logging, OwfeServiceLocator
69
80
 
70
81
  #
71
82
  # Returns the FlowExpression instance that triggered this
@@ -79,6 +90,15 @@ module OpenWFE
79
90
  @application_context[S_EXPRESSION_POOL]\
80
91
  .fetch_expression(workitem.flow_expression_id)
81
92
  end
93
+
94
+ #
95
+ # Participants use this method to reply to their engine when
96
+ # their job is done.
97
+ #
98
+ def reply_to_engine (workitem)
99
+
100
+ get_engine.reply(workitem)
101
+ end
82
102
  end
83
103
 
84
104
  end
@@ -41,6 +41,7 @@
41
41
 
42
42
  require 'openwfe/workitem'
43
43
  require 'openwfe/service'
44
+ require 'openwfe/participants/participants'
44
45
 
45
46
  include OpenWFE
46
47
 
@@ -76,9 +77,10 @@ module OpenWFE
76
77
  participant = BlockParticipant.new(block)
77
78
  end
78
79
 
79
- regex = Regexp.new(regex) if not regex.kind_of? Regexp
80
+ regex = Regexp.new(regex.to_s) unless regex.kind_of? Regexp
80
81
 
81
- participant.application_context = @application_context
82
+ participant.application_context = @application_context \
83
+ if participant.respond_to? :application_context=
82
84
 
83
85
  @participants << [ regex, participant ]
84
86
  end
@@ -39,7 +39,6 @@
39
39
  # John Mettraux at openwfe.org
40
40
  #
41
41
 
42
- require 'openwfe/rudefinitions'
43
42
  require 'openwfe/participants/participant'
44
43
 
45
44
 
@@ -48,16 +47,13 @@ require 'openwfe/participants/participant'
48
47
  #
49
48
  module OpenWFE
50
49
 
51
- class LocalParticipant
52
- include Participant, OwfeServiceLocator
53
-
54
- def reply_to_engine (workitem)
55
-
56
- get_expression_pool.reply(workitem.last_expression_id, workitem)
57
- end
58
- end
59
-
60
- class PrintParticipant < LocalParticipant
50
+ #
51
+ # The PrintParticipant will just emit its name to the
52
+ # test tracer if any or to stdout else.
53
+ # Used by some unit tests.
54
+ #
55
+ class PrintParticipant
56
+ include LocalParticipant
61
57
 
62
58
  def consume (workitem)
63
59
 
@@ -77,16 +73,15 @@ module OpenWFE
77
73
  # This participant is used by the register_participant() method of
78
74
  # Engine class.
79
75
  #
80
- # <tt>
81
- # engine.register_participant("the_boss") do |workitem|
82
- # puts "the boss received a workitem"
83
- # end
84
- # </tt>
76
+ # engine.register_participant("the_boss") do |workitem|
77
+ # puts "the boss received a workitem"
78
+ # end
85
79
  #
86
80
  # After the block executes, the BlockParticipant immediately replies
87
81
  # to the engine.
88
82
  #
89
- class BlockParticipant < LocalParticipant
83
+ class BlockParticipant
84
+ include LocalParticipant
90
85
 
91
86
  def initialize (block)
92
87
  @block = block