libis-workflow 2.0.25 → 2.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -1
- data/.gitignore +36 -36
- data/.travis.yml +32 -32
- data/Gemfile +4 -4
- data/LICENSE +20 -20
- data/README.md +380 -380
- data/Rakefile +6 -6
- data/lib/libis/exceptions.rb +6 -6
- data/lib/libis/workflow.rb +41 -41
- data/lib/libis/workflow/action.rb +24 -24
- data/lib/libis/workflow/base/dir_item.rb +13 -13
- data/lib/libis/workflow/base/file_item.rb +80 -80
- data/lib/libis/workflow/base/job.rb +83 -83
- data/lib/libis/workflow/base/logging.rb +66 -66
- data/lib/libis/workflow/base/run.rb +97 -95
- data/lib/libis/workflow/base/work_item.rb +173 -173
- data/lib/libis/workflow/base/workflow.rb +149 -149
- data/lib/libis/workflow/config.rb +22 -22
- data/lib/libis/workflow/dir_item.rb +10 -10
- data/lib/libis/workflow/file_item.rb +15 -15
- data/lib/libis/workflow/job.rb +28 -28
- data/lib/libis/workflow/message_registry.rb +30 -30
- data/lib/libis/workflow/run.rb +34 -34
- data/lib/libis/workflow/status.rb +133 -133
- data/lib/libis/workflow/task.rb +318 -316
- data/lib/libis/workflow/task_group.rb +72 -71
- data/lib/libis/workflow/task_runner.rb +34 -34
- data/lib/libis/workflow/version.rb +5 -5
- data/lib/libis/workflow/work_item.rb +37 -37
- data/lib/libis/workflow/worker.rb +42 -42
- data/lib/libis/workflow/workflow.rb +20 -20
- data/libis-workflow.gemspec +38 -38
- data/spec/items.rb +2 -2
- data/spec/items/test_dir_item.rb +13 -13
- data/spec/items/test_file_item.rb +16 -16
- data/spec/items/test_run.rb +8 -8
- data/spec/spec_helper.rb +8 -8
- data/spec/task_spec.rb +15 -15
- data/spec/tasks/camelize_name.rb +12 -12
- data/spec/tasks/checksum_tester.rb +32 -32
- data/spec/tasks/collect_files.rb +47 -47
- data/spec/workflow_spec.rb +154 -154
- metadata +3 -3
@@ -1,149 +1,149 @@
|
|
1
|
-
require 'libis/tools/parameter'
|
2
|
-
require 'libis/workflow/task_group'
|
3
|
-
require 'libis/tools/extend/hash'
|
4
|
-
|
5
|
-
module Libis
|
6
|
-
module Workflow
|
7
|
-
module Base
|
8
|
-
|
9
|
-
# This is the base module for Workflows.
|
10
|
-
#
|
11
|
-
# This module lacks the implementation for the data attributes. It functions as an interface that describes the
|
12
|
-
# common functionality regardless of the storage implementation. These attributes require some implementation:
|
13
|
-
#
|
14
|
-
# - name: [String] the name of the Workflow. The name will be used to identify the workflow. Each time a workflow
|
15
|
-
# is executed, a Run will be created. The Run will get a name that starts with the workflow name and ends with
|
16
|
-
# the date and time the Run was started. As such this name attribute serves as an identifier and should be
|
17
|
-
# treated as such. If possible is should be unique.
|
18
|
-
# - description: [String] more information about the workflow.
|
19
|
-
# - config: [Hash] detailed configuration for the workflow. The application assumes it behaves as a Hash and will
|
20
|
-
# access it with [], merge! and delete methods. If your implementation decides to implement it with another
|
21
|
-
# object, it should implement above methods. The config Hash requires the following keys:
|
22
|
-
# - input: [Hash] all input parameter definitions where the key is the parameter name and the value is another
|
23
|
-
# Hash with arguments for the parameter definition. It typically contains the following arguments:
|
24
|
-
# - default: default value if no value specified when the workflow is executed
|
25
|
-
# - propagate_to: the task name (or path) and parameter name that any set value for this parameter will be
|
26
|
-
# propagated to. The syntax is <task name|task path>[#<parameter name>]. It the #<parameter name> part
|
27
|
-
# is not present, the same name as the input parameter is used. If you want to push the value to
|
28
|
-
# multiple task parameters, you can either supply an array of propagate paths or put them in a string
|
29
|
-
# separated by a ','.
|
30
|
-
# - tasks: [Array] task definitions that define the order in which the tasks should be executed for the workflow.
|
31
|
-
# A task definition is a Hash with the following values:
|
32
|
-
# - class: [String] the class name of the task including the module names
|
33
|
-
# - name: [String] optional if class is present. A friendly name for the task that will be used in the logs.
|
34
|
-
# - tasks: [Array] a list of subtask defintions for this task.
|
35
|
-
#
|
36
|
-
# Additionally the task definition Hash may specify values for any other parameter that the task knows of.
|
37
|
-
# All tasks have some fixed parameters. For more information about these see the documentation of
|
38
|
-
# the task class.
|
39
|
-
#
|
40
|
-
# A task definition does not require to have a 'class' entry. If not present the default
|
41
|
-
# ::Libis::Workflow::TaskGroup class will be instatiated. It will do nothing itself, but will execute the
|
42
|
-
# subtasks on the item(s). In such case a 'name' is mandatory.
|
43
|
-
#
|
44
|
-
# These values should be set by calling the #configure method which takes a Hash as argument with :name,
|
45
|
-
# :description, :input and :tasks keys.
|
46
|
-
#
|
47
|
-
# A minimal in-memory implementation could be:
|
48
|
-
#
|
49
|
-
# class Workflow
|
50
|
-
# include ::Libis::Workflow::Base::Workflow
|
51
|
-
#
|
52
|
-
# attr_accessor :name, :description, :config
|
53
|
-
#
|
54
|
-
# def initialize
|
55
|
-
# @name = ''
|
56
|
-
# @description = ''
|
57
|
-
# @config = Hash.new
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
module Workflow
|
63
|
-
|
64
|
-
module ClassMethods
|
65
|
-
def require_all
|
66
|
-
Libis::Workflow::Config.require_all(File.join(File.dirname(__FILE__), '..', 'tasks'))
|
67
|
-
# noinspection RubyResolve
|
68
|
-
Libis::Workflow::Config.require_all(Libis::Workflow::Config.taskdir)
|
69
|
-
# noinspection RubyResolve
|
70
|
-
Libis::Workflow::Config.require_all(Libis::Workflow::Config.itemdir)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.included(base)
|
75
|
-
base.extend ClassMethods
|
76
|
-
end
|
77
|
-
|
78
|
-
def configure(cfg)
|
79
|
-
self.name = cfg.delete('name') || self.class.name
|
80
|
-
self.description = cfg.delete('description') || ''
|
81
|
-
self.config['input'] = {}
|
82
|
-
self.config['tasks'] = []
|
83
|
-
self.config.merge! cfg
|
84
|
-
|
85
|
-
self.class.require_all
|
86
|
-
|
87
|
-
self.config
|
88
|
-
end
|
89
|
-
|
90
|
-
def input
|
91
|
-
self.config.key_strings_to_symbols(recursive: true)[:input].inject({}) do |hash, input_def|
|
92
|
-
name = input_def.first
|
93
|
-
default = input_def.last[:default]
|
94
|
-
parameter = ::Libis::Tools::Parameter.new name, default
|
95
|
-
input_def.last.each { |k, v| parameter[k] = v }
|
96
|
-
hash[name] = parameter
|
97
|
-
hash
|
98
|
-
end
|
99
|
-
rescue
|
100
|
-
{}
|
101
|
-
end
|
102
|
-
|
103
|
-
# @param [Hash] options
|
104
|
-
def prepare_input(options)
|
105
|
-
options = options.key_strings_to_symbols
|
106
|
-
result = {}
|
107
|
-
self.input.each do |key, parameter|
|
108
|
-
if options.has_key?(key)
|
109
|
-
value = parameter.parse(options[key])
|
110
|
-
elsif !parameter[:default].nil?
|
111
|
-
value = parameter[:default]
|
112
|
-
else
|
113
|
-
next
|
114
|
-
end
|
115
|
-
propagate_to = []
|
116
|
-
propagate_to = parameter[:propagate_to] if parameter[:propagate_to].is_a? Array
|
117
|
-
propagate_to = parameter[:propagate_to].split(/[\s,;]+/) if parameter[:propagate_to].is_a? String
|
118
|
-
result[key] = value if propagate_to.empty?
|
119
|
-
propagate_to.each do |target|
|
120
|
-
task_name, param_name = target.split('#')
|
121
|
-
param_name ||= key.to_s
|
122
|
-
result[task_name] ||= {}
|
123
|
-
result[task_name][param_name] = value
|
124
|
-
end
|
125
|
-
end
|
126
|
-
result
|
127
|
-
end
|
128
|
-
|
129
|
-
def tasks(parent = nil)
|
130
|
-
self.config['tasks'].map do |cfg|
|
131
|
-
instantize_task(parent || nil, cfg)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def instantize_task(parent, cfg)
|
136
|
-
task_class = Libis::Workflow::TaskGroup
|
137
|
-
task_class = cfg['class'].constantize if cfg['class']
|
138
|
-
# noinspection RubyArgCount
|
139
|
-
task_instance = task_class.new(parent, cfg)
|
140
|
-
cfg['tasks'] && cfg['tasks'].map do |task_cfg|
|
141
|
-
task_instance << instantize_task(task_instance, task_cfg)
|
142
|
-
end
|
143
|
-
task_instance
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
1
|
+
require 'libis/tools/parameter'
|
2
|
+
require 'libis/workflow/task_group'
|
3
|
+
require 'libis/tools/extend/hash'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Workflow
|
7
|
+
module Base
|
8
|
+
|
9
|
+
# This is the base module for Workflows.
|
10
|
+
#
|
11
|
+
# This module lacks the implementation for the data attributes. It functions as an interface that describes the
|
12
|
+
# common functionality regardless of the storage implementation. These attributes require some implementation:
|
13
|
+
#
|
14
|
+
# - name: [String] the name of the Workflow. The name will be used to identify the workflow. Each time a workflow
|
15
|
+
# is executed, a Run will be created. The Run will get a name that starts with the workflow name and ends with
|
16
|
+
# the date and time the Run was started. As such this name attribute serves as an identifier and should be
|
17
|
+
# treated as such. If possible is should be unique.
|
18
|
+
# - description: [String] more information about the workflow.
|
19
|
+
# - config: [Hash] detailed configuration for the workflow. The application assumes it behaves as a Hash and will
|
20
|
+
# access it with [], merge! and delete methods. If your implementation decides to implement it with another
|
21
|
+
# object, it should implement above methods. The config Hash requires the following keys:
|
22
|
+
# - input: [Hash] all input parameter definitions where the key is the parameter name and the value is another
|
23
|
+
# Hash with arguments for the parameter definition. It typically contains the following arguments:
|
24
|
+
# - default: default value if no value specified when the workflow is executed
|
25
|
+
# - propagate_to: the task name (or path) and parameter name that any set value for this parameter will be
|
26
|
+
# propagated to. The syntax is <task name|task path>[#<parameter name>]. It the #<parameter name> part
|
27
|
+
# is not present, the same name as the input parameter is used. If you want to push the value to
|
28
|
+
# multiple task parameters, you can either supply an array of propagate paths or put them in a string
|
29
|
+
# separated by a ','.
|
30
|
+
# - tasks: [Array] task definitions that define the order in which the tasks should be executed for the workflow.
|
31
|
+
# A task definition is a Hash with the following values:
|
32
|
+
# - class: [String] the class name of the task including the module names
|
33
|
+
# - name: [String] optional if class is present. A friendly name for the task that will be used in the logs.
|
34
|
+
# - tasks: [Array] a list of subtask defintions for this task.
|
35
|
+
#
|
36
|
+
# Additionally the task definition Hash may specify values for any other parameter that the task knows of.
|
37
|
+
# All tasks have some fixed parameters. For more information about these see the documentation of
|
38
|
+
# the task class.
|
39
|
+
#
|
40
|
+
# A task definition does not require to have a 'class' entry. If not present the default
|
41
|
+
# ::Libis::Workflow::TaskGroup class will be instatiated. It will do nothing itself, but will execute the
|
42
|
+
# subtasks on the item(s). In such case a 'name' is mandatory.
|
43
|
+
#
|
44
|
+
# These values should be set by calling the #configure method which takes a Hash as argument with :name,
|
45
|
+
# :description, :input and :tasks keys.
|
46
|
+
#
|
47
|
+
# A minimal in-memory implementation could be:
|
48
|
+
#
|
49
|
+
# class Workflow
|
50
|
+
# include ::Libis::Workflow::Base::Workflow
|
51
|
+
#
|
52
|
+
# attr_accessor :name, :description, :config
|
53
|
+
#
|
54
|
+
# def initialize
|
55
|
+
# @name = ''
|
56
|
+
# @description = ''
|
57
|
+
# @config = Hash.new
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
module Workflow
|
63
|
+
|
64
|
+
module ClassMethods
|
65
|
+
def require_all
|
66
|
+
Libis::Workflow::Config.require_all(File.join(File.dirname(__FILE__), '..', 'tasks'))
|
67
|
+
# noinspection RubyResolve
|
68
|
+
Libis::Workflow::Config.require_all(Libis::Workflow::Config.taskdir)
|
69
|
+
# noinspection RubyResolve
|
70
|
+
Libis::Workflow::Config.require_all(Libis::Workflow::Config.itemdir)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.included(base)
|
75
|
+
base.extend ClassMethods
|
76
|
+
end
|
77
|
+
|
78
|
+
def configure(cfg)
|
79
|
+
self.name = cfg.delete('name') || self.class.name
|
80
|
+
self.description = cfg.delete('description') || ''
|
81
|
+
self.config['input'] = {}
|
82
|
+
self.config['tasks'] = []
|
83
|
+
self.config.merge! cfg
|
84
|
+
|
85
|
+
self.class.require_all
|
86
|
+
|
87
|
+
self.config
|
88
|
+
end
|
89
|
+
|
90
|
+
def input
|
91
|
+
self.config.key_strings_to_symbols(recursive: true)[:input].inject({}) do |hash, input_def|
|
92
|
+
name = input_def.first
|
93
|
+
default = input_def.last[:default]
|
94
|
+
parameter = ::Libis::Tools::Parameter.new name, default
|
95
|
+
input_def.last.each { |k, v| parameter[k] = v }
|
96
|
+
hash[name] = parameter
|
97
|
+
hash
|
98
|
+
end
|
99
|
+
rescue
|
100
|
+
{}
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param [Hash] options
|
104
|
+
def prepare_input(options)
|
105
|
+
options = options.key_strings_to_symbols
|
106
|
+
result = {}
|
107
|
+
self.input.each do |key, parameter|
|
108
|
+
if options.has_key?(key)
|
109
|
+
value = parameter.parse(options[key])
|
110
|
+
elsif !parameter[:default].nil?
|
111
|
+
value = parameter[:default]
|
112
|
+
else
|
113
|
+
next
|
114
|
+
end
|
115
|
+
propagate_to = []
|
116
|
+
propagate_to = parameter[:propagate_to] if parameter[:propagate_to].is_a? Array
|
117
|
+
propagate_to = parameter[:propagate_to].split(/[\s,;]+/) if parameter[:propagate_to].is_a? String
|
118
|
+
result[key] = value if propagate_to.empty?
|
119
|
+
propagate_to.each do |target|
|
120
|
+
task_name, param_name = target.split('#')
|
121
|
+
param_name ||= key.to_s
|
122
|
+
result[task_name] ||= {}
|
123
|
+
result[task_name][param_name] = value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
result
|
127
|
+
end
|
128
|
+
|
129
|
+
def tasks(parent = nil)
|
130
|
+
self.config['tasks'].map do |cfg|
|
131
|
+
instantize_task(parent || nil, cfg)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def instantize_task(parent, cfg)
|
136
|
+
task_class = Libis::Workflow::TaskGroup
|
137
|
+
task_class = cfg['class'].constantize if cfg['class']
|
138
|
+
# noinspection RubyArgCount
|
139
|
+
task_instance = task_class.new(parent, cfg)
|
140
|
+
cfg['tasks'] && cfg['tasks'].map do |task_cfg|
|
141
|
+
task_instance << instantize_task(task_instance, task_cfg)
|
142
|
+
end
|
143
|
+
task_instance
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require 'libis/tools/config'
|
2
|
-
|
3
|
-
module Libis
|
4
|
-
module Workflow
|
5
|
-
|
6
|
-
# noinspection RubyConstantNamingConvention
|
7
|
-
Config = ::Libis::Tools::Config
|
8
|
-
|
9
|
-
Config.define_singleton_method(:require_all) do |dir|
|
10
|
-
Dir.glob(File.join(dir, '*.rb')).each do |filename|
|
11
|
-
# noinspection RubyResolve
|
12
|
-
require filename
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
Config.require_all(File.join(File.dirname(__FILE__), 'tasks'))
|
17
|
-
Config[:workdir] = './work'
|
18
|
-
Config[:taskdir] = './tasks'
|
19
|
-
Config[:itemdir] = './items'
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
1
|
+
require 'libis/tools/config'
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Workflow
|
5
|
+
|
6
|
+
# noinspection RubyConstantNamingConvention
|
7
|
+
Config = ::Libis::Tools::Config
|
8
|
+
|
9
|
+
Config.define_singleton_method(:require_all) do |dir|
|
10
|
+
Dir.glob(File.join(dir, '*.rb')).each do |filename|
|
11
|
+
# noinspection RubyResolve
|
12
|
+
require filename
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Config.require_all(File.join(File.dirname(__FILE__), 'tasks'))
|
17
|
+
Config[:workdir] = './work'
|
18
|
+
Config[:taskdir] = './tasks'
|
19
|
+
Config[:itemdir] = './items'
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'libis/workflow/file_item'
|
2
|
-
|
3
|
-
module Libis
|
4
|
-
module Workflow
|
5
|
-
|
6
|
-
class DirItem < ::Libis::Workflow::FileItem
|
7
|
-
end
|
8
|
-
|
9
|
-
end
|
10
|
-
end
|
1
|
+
require 'libis/workflow/file_item'
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Workflow
|
5
|
+
|
6
|
+
class DirItem < ::Libis::Workflow::FileItem
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'digest'
|
2
|
-
|
3
|
-
require 'libis/workflow/base/file_item'
|
4
|
-
require 'libis/workflow/work_item'
|
5
|
-
|
6
|
-
module Libis
|
7
|
-
module Workflow
|
8
|
-
|
9
|
-
# noinspection RubyResolve
|
10
|
-
class FileItem < ::Libis::Workflow::WorkItem
|
11
|
-
include ::Libis::Workflow::Base::FileItem
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
require 'libis/workflow/base/file_item'
|
4
|
+
require 'libis/workflow/work_item'
|
5
|
+
|
6
|
+
module Libis
|
7
|
+
module Workflow
|
8
|
+
|
9
|
+
# noinspection RubyResolve
|
10
|
+
class FileItem < ::Libis::Workflow::WorkItem
|
11
|
+
include ::Libis::Workflow::Base::FileItem
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/libis/workflow/job.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
require 'libis/workflow/base/job'
|
2
|
-
require 'libis/workflow/workflow'
|
3
|
-
require 'libis/workflow/run'
|
4
|
-
|
5
|
-
module Libis
|
6
|
-
module Workflow
|
7
|
-
|
8
|
-
class Job
|
9
|
-
include ::Libis::Workflow::Base::Job
|
10
|
-
|
11
|
-
attr_accessor :name, :description, :workflow, :run_object, :input
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@name = ''
|
15
|
-
@description = ''
|
16
|
-
@input = Hash.new
|
17
|
-
@workflow = ::Libis::Workflow::Workflow.new
|
18
|
-
@run_object = ::Libis::Workflow::Run.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def logger
|
22
|
-
::Libis::Workflow::Config.logger
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
1
|
+
require 'libis/workflow/base/job'
|
2
|
+
require 'libis/workflow/workflow'
|
3
|
+
require 'libis/workflow/run'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Workflow
|
7
|
+
|
8
|
+
class Job
|
9
|
+
include ::Libis::Workflow::Base::Job
|
10
|
+
|
11
|
+
attr_accessor :name, :description, :workflow, :run_object, :input
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@name = ''
|
15
|
+
@description = ''
|
16
|
+
@input = Hash.new
|
17
|
+
@workflow = ::Libis::Workflow::Workflow.new
|
18
|
+
@run_object = ::Libis::Workflow::Run.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def logger
|
22
|
+
::Libis::Workflow::Config.logger
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|