ruote-kit 2.1.8.2 → 2.1.10
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.
- data/.gitignore +1 -0
- data/Gemfile +20 -4
- data/README.rdoc +62 -13
- data/Rakefile +9 -12
- data/config.ru +22 -5
- data/lib/ruote-kit.rb +2 -3
- data/lib/ruote-kit/application.rb +1 -1
- data/lib/ruote-kit/helpers/launch_item_parser.rb +5 -5
- data/lib/ruote-kit/helpers/render_helpers.rb +42 -25
- data/lib/ruote-kit/resources/errors.rb +65 -0
- data/lib/ruote-kit/resources/expressions.rb +1 -1
- data/lib/ruote-kit/resources/processes.rb +2 -1
- data/lib/ruote-kit/resources/workitems.rb +8 -9
- data/lib/ruote-kit/spec/ruote_helpers.rb +1 -1
- data/lib/ruote-kit/version.rb +1 -1
- data/lib/ruote-kit/views/errors.html.haml +18 -0
- data/lib/ruote-kit/views/workitem.html.haml +3 -3
- data/ruote-kit.gemspec +24 -11
- data/spec/resources/errors_spec.rb +292 -0
- data/spec/resources/processes_spec.rb +4 -3
- data/spec/resources/workitems_spec.rb +55 -13
- data/spec/spec_helper.rb +6 -7
- metadata +91 -18
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -6,14 +6,30 @@ gem 'bundler'
|
|
6
6
|
gem 'sinatra'
|
7
7
|
gem 'sinatra-respond_to'
|
8
8
|
gem 'haml'
|
9
|
-
|
9
|
+
|
10
|
+
# json support
|
11
|
+
#
|
12
|
+
# you should choose one of the following three or add another backend supported
|
13
|
+
# by Rufus::Json (http://github.com/jmettraux/rufus-json/)
|
14
|
+
#
|
15
|
+
# gem 'json_pure' # safest all-around choice
|
16
|
+
# gem 'yajl-ruby' # the fastest, but using c code
|
17
|
+
# gem 'json' # not bad, but using c code and sometimes broken
|
18
|
+
#
|
19
|
+
# needed, uses one of the above as backend
|
20
|
+
gem 'rufus-json', '>= 0.2.3'
|
10
21
|
|
11
22
|
# ruote
|
12
|
-
|
13
|
-
gem 'ruote', '>= 2.1.8'
|
23
|
+
gem 'ruote', '>= 2.1.10'
|
14
24
|
|
15
25
|
# Testing environment requirements
|
16
26
|
group :test do
|
17
|
-
gem 'rspec'
|
27
|
+
gem 'rspec', :require => "spec"
|
28
|
+
gem 'rack-test'
|
29
|
+
gem 'webrat'
|
30
|
+
gem 'test-unit', '~> 1.2.3'
|
31
|
+
end
|
32
|
+
|
33
|
+
group :build do
|
18
34
|
gem 'jeweler'
|
19
35
|
end
|
data/README.rdoc
CHANGED
@@ -18,13 +18,13 @@ Follow development:
|
|
18
18
|
ruote-kit is under heavy development and will likely change violently over the
|
19
19
|
coming weeks (albeit for the better).
|
20
20
|
|
21
|
-
Dependencies you currently need
|
21
|
+
Dependencies you currently need are:
|
22
22
|
|
23
23
|
* bundler 0.9.5 or later (gem install bundler)
|
24
24
|
* sinatra
|
25
25
|
* sinatra-respond_to
|
26
26
|
* haml
|
27
|
-
* json
|
27
|
+
* rufus-json[http://github.com/jmettraux/rufus-json] and a compatible backend
|
28
28
|
* rspec (only to run the specs)
|
29
29
|
|
30
30
|
ruote-kit uses bundler to setup and maintain its environment. Before running
|
@@ -38,12 +38,64 @@ unpacked in .bundle
|
|
38
38
|
|
39
39
|
== Getting started quickly
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
=== Using the RubyGem
|
42
|
+
|
43
|
+
* Install the gem and its dependencies
|
44
|
+
$ gem install ruote-kit
|
45
|
+
* You'll need an empty directory
|
46
|
+
$ mkdir my-ruote-kit && cd my-ruote-kit
|
47
|
+
* There are two files needed in that directory: Gemfile and config.ru
|
48
|
+
* Gemfile
|
49
|
+
source :gemcutter
|
50
|
+
gem 'ruote-kit'
|
51
|
+
* config.ru
|
52
|
+
begin
|
53
|
+
# Try to require the preresolved locked set of gems.
|
54
|
+
require ::File.expand_path('.bundle/environment', __FILE__)
|
55
|
+
rescue LoadError
|
56
|
+
# Fall back on doing an unlocked resolve at runtime.
|
57
|
+
require "rubygems"
|
58
|
+
require "bundler"
|
59
|
+
Bundler.setup(:default)
|
60
|
+
end
|
61
|
+
|
62
|
+
# load json backend
|
63
|
+
require 'yajl-ruby' # best choice as fastest, but uses a c module
|
64
|
+
# require 'json_pure' # should work everywhere
|
65
|
+
|
66
|
+
require 'ruote-kit'
|
67
|
+
|
68
|
+
RuoteKit.configure do |config|
|
69
|
+
config.register { catchall }
|
70
|
+
end
|
71
|
+
|
72
|
+
use Rack::CommonLogger
|
73
|
+
use Rack::Lint
|
74
|
+
|
75
|
+
run RuoteKit::Application
|
76
|
+
* Just to make sure every dependency is resolved
|
77
|
+
$ bundle check
|
78
|
+
* If there are missing dependencies (there shouldn't be any if the gem
|
79
|
+
installation succeeded)
|
80
|
+
$ bundle install
|
81
|
+
* Get going
|
82
|
+
$ rackup
|
83
|
+
|
84
|
+
=== Using the source
|
85
|
+
|
86
|
+
* Get the source files using git
|
87
|
+
$ git clone http://github.com/kennethkalmer/ruote-kit.git && cd ruote-kit
|
88
|
+
* Make sure every dependency is resolved
|
89
|
+
$ bundle install
|
90
|
+
* Get going
|
91
|
+
$ rackup
|
92
|
+
|
93
|
+
=== Accessing the web interface
|
43
94
|
|
44
95
|
If ruote-kit starts up without any issues (ie missing dependencies), you can
|
45
|
-
point your browser to 'http://localhost:9292/_ruote/' to get going.
|
46
|
-
binds to all IP addresses, so this works out the box
|
96
|
+
point your browser to 'http://localhost:9292/_ruote/' to get going.
|
97
|
+
By default ruote-kit binds to all IP addresses, so this works out the box
|
98
|
+
remotely too.
|
47
99
|
|
48
100
|
== Plugging ruote-kit into your rack-stack
|
49
101
|
|
@@ -105,11 +157,8 @@ You may also use the catchall participant provided by RuoteKit. It's named '.+',
|
|
105
157
|
so it will catch all workitems for any participant mentioned in your workflow
|
106
158
|
definitions which are not already caught by another (previously) registered
|
107
159
|
participant. So make sure to register the catchall after your own participants.
|
108
|
-
The catchall participant may be registered by calling
|
109
|
-
|
110
|
-
catchall
|
111
|
-
|
112
|
-
within the block given to RuoteKit::Configuration#register (this will use
|
160
|
+
The catchall participant may be registered by calling +catchall+ within the
|
161
|
+
block given to RuoteKit::Configuration#register (this will use
|
113
162
|
Ruote::StorageParticipant as participant implementation, you may use any options
|
114
163
|
of Ruote::Engine#register_participant to overwrite that default -- see the
|
115
164
|
example above).
|
@@ -117,11 +166,11 @@ example above).
|
|
117
166
|
== Running workers
|
118
167
|
|
119
168
|
If you're using ruote-kit as part of your rack stack you'll need to start at
|
120
|
-
least one worker separately or the workflows
|
169
|
+
least one worker separately or the workflows won't be executed. You won't need
|
121
170
|
more than one worker unless you are running hundreds of processes at the same
|
122
171
|
time.
|
123
172
|
|
124
|
-
To run a worker you need to setup a worker
|
173
|
+
To run a worker you need to setup a worker script similar to the rake example
|
125
174
|
below:
|
126
175
|
|
127
176
|
require 'rake'
|
data/Rakefile
CHANGED
@@ -1,15 +1,9 @@
|
|
1
1
|
|
2
2
|
require 'rake/tasklib'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
rescue LoadError
|
8
|
-
# Fall back on doing an unlocked resolve at runtime.
|
9
|
-
require "rubygems"
|
10
|
-
require "bundler"
|
11
|
-
Bundler.setup
|
12
|
-
end
|
4
|
+
require "rubygems"
|
5
|
+
require "bundler"
|
6
|
+
Bundler.setup(:default, :test, :build)
|
13
7
|
|
14
8
|
require 'lib/ruote-kit/version'
|
15
9
|
|
@@ -22,7 +16,7 @@ begin
|
|
22
16
|
gemspec.description = 'ruote-kit is a RESTful Rack app for the ruote workflow engine'
|
23
17
|
gemspec.email = 'kenneth.kalmer@gmail.com'
|
24
18
|
gemspec.homepage = 'http://github.com/kennethkalmer/ruote-kit'
|
25
|
-
gemspec.authors = ['kenneth.kalmer@gmail.com']
|
19
|
+
gemspec.authors = ['kenneth.kalmer@gmail.com', 'John Mettraux']
|
26
20
|
gemspec.extra_rdoc_files.include '*.txt'
|
27
21
|
|
28
22
|
gemspec.files.include 'lib/ruote-kit/public/**/*'
|
@@ -32,11 +26,14 @@ begin
|
|
32
26
|
gemspec.add_dependency 'sinatra', '>=0.9.4'
|
33
27
|
gemspec.add_dependency 'sinatra-respond_to', '>=0.4.0'
|
34
28
|
gemspec.add_dependency 'haml', '>= 2.2.5'
|
35
|
-
gemspec.add_dependency 'json'
|
36
|
-
gemspec.add_dependency 'ruote', '>= 2.1.
|
29
|
+
gemspec.add_dependency 'rufus-json', '>= 0.2.3'
|
30
|
+
gemspec.add_dependency 'ruote', '>= 2.1.10'
|
37
31
|
gemspec.add_development_dependency 'rake'
|
38
32
|
gemspec.add_development_dependency 'rspec'
|
39
33
|
gemspec.add_development_dependency 'jeweler'
|
34
|
+
gemspec.add_development_dependency 'webrat'
|
35
|
+
gemspec.add_development_dependency 'test-unit', '~> 1.2.3'
|
36
|
+
gemspec.add_development_dependency 'rack-test'
|
40
37
|
end
|
41
38
|
Jeweler::GemcutterTasks.new
|
42
39
|
rescue LoadError
|
data/config.ru
CHANGED
@@ -1,20 +1,36 @@
|
|
1
|
+
|
1
2
|
begin
|
2
3
|
# Try to require the preresolved locked set of gems.
|
3
4
|
require ::File.expand_path('.bundle/environment', __FILE__)
|
4
5
|
rescue LoadError
|
5
6
|
# Fall back on doing an unlocked resolve at runtime.
|
6
|
-
require
|
7
|
-
require
|
8
|
-
Bundler.setup
|
7
|
+
require 'rubygems'
|
8
|
+
require 'bundler'
|
9
|
+
Bundler.setup(:default)
|
9
10
|
end
|
10
11
|
|
12
|
+
# load json support
|
13
|
+
# try yajl-ruby first, and json after that
|
14
|
+
begin
|
15
|
+
require 'yajl'
|
16
|
+
rescue LoadError
|
17
|
+
begin
|
18
|
+
require 'json'
|
19
|
+
rescue LoadError
|
20
|
+
puts 'Please specify "gem {yajl-ruby|json_pure|json}" in the Gemfile'
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rufus-json'
|
26
|
+
|
11
27
|
$:.unshift 'lib'
|
12
28
|
|
13
|
-
require '
|
29
|
+
require 'ruote-kit'
|
14
30
|
|
15
31
|
# Chance to configure ruote-kit
|
16
32
|
RuoteKit.configure do |config|
|
17
|
-
|
33
|
+
|
18
34
|
# storage mode
|
19
35
|
#config.mode = :transient
|
20
36
|
|
@@ -33,3 +49,4 @@ use Rack::Lint
|
|
33
49
|
use Rack::ShowExceptions
|
34
50
|
|
35
51
|
run RuoteKit::Application
|
52
|
+
|
data/lib/ruote-kit.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
require 'json'
|
1
|
+
require 'rufus-json'
|
2
2
|
require 'ruote'
|
3
3
|
require 'ruote/part/storage_participant'
|
4
|
+
require 'ruote-kit/version'
|
4
5
|
|
5
6
|
module RuoteKit
|
6
7
|
|
7
|
-
VERSION = '2.1.8.2'
|
8
|
-
|
9
8
|
autoload :Configuration, "ruote-kit/configuration"
|
10
9
|
autoload :Application, "ruote-kit/application"
|
11
10
|
autoload :Helpers, "ruote-kit/helpers"
|
@@ -7,7 +7,7 @@ module RuoteKit
|
|
7
7
|
case env["CONTENT_TYPE"]
|
8
8
|
|
9
9
|
when "application/json" then
|
10
|
-
data =
|
10
|
+
data = Rufus::Json.decode( env["rack.input"].read )
|
11
11
|
launch_item = {}
|
12
12
|
launch_item['pdef'] = data["definition"]
|
13
13
|
launch_item['fields'] = data["fields"] || {}
|
@@ -18,10 +18,10 @@ module RuoteKit
|
|
18
18
|
launch_item = { 'pdef' => params[:process_definition] }
|
19
19
|
fields = params[:process_fields] || ""
|
20
20
|
fields = "{}" if fields.empty?
|
21
|
-
launch_item['fields'] =
|
21
|
+
launch_item['fields'] = Rufus::Json.decode( fields )
|
22
22
|
vars = params[:process_variables] || ""
|
23
23
|
vars = "{}" if vars.empty?
|
24
|
-
launch_item['variables'] =
|
24
|
+
launch_item['variables'] = Rufus::Json.decode( vars )
|
25
25
|
return launch_item
|
26
26
|
|
27
27
|
else
|
@@ -38,12 +38,12 @@ module RuoteKit
|
|
38
38
|
case env['CONTENT_TYPE']
|
39
39
|
|
40
40
|
when "application/json" then
|
41
|
-
data =
|
41
|
+
data = Rufus::Json.decode( env['rack.input'].read )
|
42
42
|
options[:fields] = data['fields'] unless data['fields'].nil? || data['fields'].empty?
|
43
43
|
options[:proceed] = data['_proceed'] unless data['_proceed'].nil? || data['_proceed'].empty?
|
44
44
|
|
45
45
|
when "application/x-www-form-urlencoded"
|
46
|
-
options[:fields] =
|
46
|
+
options[:fields] = Rufus::Json.decode( params[:fields] ) unless params['fields'].nil? || params['fields'].empty?
|
47
47
|
options[:proceed] = params[:_proceed] unless params[:_proceed].nil? || params[:_proceed].empty?
|
48
48
|
|
49
49
|
else
|
@@ -8,10 +8,10 @@ module RuoteKit
|
|
8
8
|
object = send( "json_#{resource}", object )
|
9
9
|
end
|
10
10
|
|
11
|
-
{
|
11
|
+
Rufus::Json.encode( {
|
12
12
|
"links" => links( resource ),
|
13
|
-
resource => object
|
14
|
-
}
|
13
|
+
resource.to_s => object
|
14
|
+
} )
|
15
15
|
end
|
16
16
|
|
17
17
|
def json_processes( processes )
|
@@ -20,9 +20,9 @@ module RuoteKit
|
|
20
20
|
|
21
21
|
def json_process( process )
|
22
22
|
links = [
|
23
|
-
link( "/_ruote/processes/#{process.wfid}",
|
24
|
-
link( "/_ruote/expressions/#{process.wfid}",
|
25
|
-
link( "/_ruote/workitems/#{process.wfid}",
|
23
|
+
link( "/_ruote/processes/#{process.wfid}", '#process' ),
|
24
|
+
link( "/_ruote/expressions/#{process.wfid}", '#expressions' ),
|
25
|
+
link( "/_ruote/workitems/#{process.wfid}", '#workitems' )
|
26
26
|
]
|
27
27
|
|
28
28
|
process.to_h.merge( 'links' => links )
|
@@ -30,8 +30,8 @@ module RuoteKit
|
|
30
30
|
|
31
31
|
def json_expression( expression )
|
32
32
|
links = [
|
33
|
-
link( "/_ruote/processes/#{expression.fei.wfid}",
|
34
|
-
link( "/_ruote/expressions/#{expression.fei.wfid}",
|
33
|
+
link( "/_ruote/processes/#{expression.fei.wfid}", '#process' ),
|
34
|
+
link( "/_ruote/expressions/#{expression.fei.wfid}", '#expressions' )
|
35
35
|
]
|
36
36
|
|
37
37
|
if expression.parent
|
@@ -50,40 +50,58 @@ module RuoteKit
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def json_workitem( workitem )
|
53
|
+
|
53
54
|
links = [
|
54
|
-
link( "/_ruote/processes/#{workitem.fei.wfid}",
|
55
|
-
link( "/_ruote/expressions/#{workitem.fei.wfid}",
|
55
|
+
link( "/_ruote/processes/#{workitem.fei.wfid}", '#process' ),
|
56
|
+
link( "/_ruote/expressions/#{workitem.fei.wfid}", '#expressions' ),
|
57
|
+
link( "/_ruote/errors/#{workitem.fei.wfid}", '#errors' )
|
56
58
|
]
|
57
59
|
|
58
60
|
workitem.to_h.merge( 'links' => links )
|
59
61
|
end
|
60
62
|
|
61
|
-
def
|
62
|
-
|
63
|
+
def json_errors( errors )
|
64
|
+
errors.collect { |e| json_error( e, false ) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def json_error( error )
|
68
|
+
error.to_h.merge( 'links' => links )
|
63
69
|
end
|
64
70
|
|
65
71
|
def links( resource )
|
66
|
-
|
67
|
-
link( '/_ruote',
|
68
|
-
link( '/_ruote/processes',
|
69
|
-
link( '/_ruote/workitems',
|
70
|
-
link( '/_ruote/
|
72
|
+
[
|
73
|
+
link( '/_ruote', '#root' ),
|
74
|
+
link( '/_ruote/processes', '#processes' ),
|
75
|
+
link( '/_ruote/workitems', '#workitems' ),
|
76
|
+
link( '/_ruote/errors', '#errors' ),
|
77
|
+
link( '/_ruote/history', '#history' ),
|
71
78
|
link( request.fullpath, 'self' )
|
72
79
|
]
|
73
|
-
|
74
|
-
links
|
75
80
|
end
|
76
81
|
|
77
82
|
def link( href, rel )
|
78
|
-
{
|
83
|
+
{
|
84
|
+
'href' => href,
|
85
|
+
'rel' => rel.match(/^#/) ? "http://ruote.rubyforge.org/rels.html#{rel}" : rel
|
86
|
+
}
|
79
87
|
end
|
80
88
|
|
81
89
|
# Easy 404
|
90
|
+
#
|
82
91
|
def resource_not_found
|
92
|
+
|
83
93
|
status 404
|
94
|
+
|
95
|
+
@format = if m = @format.to_s.match(/^[^\/]+\/([^;]+)/)
|
96
|
+
m[1].to_sym
|
97
|
+
else
|
98
|
+
@format
|
99
|
+
end
|
100
|
+
# freaking sinata-respond_to 0.4.0... (or is that it ?)
|
101
|
+
|
84
102
|
respond_to do |format|
|
85
103
|
format.html { haml :resource_not_found }
|
86
|
-
format.json { { "error" => { "code" => 404, "message" => "Resource not found" } }
|
104
|
+
format.json { Rufus::Json.encode( { "error" => { "code" => 404, "message" => "Resource not found" } } ) }
|
87
105
|
end
|
88
106
|
end
|
89
107
|
|
@@ -92,7 +110,7 @@ module RuoteKit
|
|
92
110
|
status 503
|
93
111
|
respond_to do |format|
|
94
112
|
format.html { haml :workitems_not_available }
|
95
|
-
format.json { { "error" => { "code" => 503, "messages" => "Workitems not available" } }
|
113
|
+
format.json { Rufus::Json.encode( { "error" => { "code" => 503, "messages" => "Workitems not available" } } ) }
|
96
114
|
end
|
97
115
|
end
|
98
116
|
|
@@ -101,12 +119,11 @@ module RuoteKit
|
|
101
119
|
case object
|
102
120
|
when Ruote::Workitem
|
103
121
|
process = engine.process( object.fei.wfid )
|
104
|
-
process.current_tree
|
122
|
+
Rufus::Json.encode( process.current_tree )
|
105
123
|
when Ruote::ProcessStatus
|
106
|
-
object.current_tree
|
124
|
+
Rufus::Json.encode( object.current_tree )
|
107
125
|
end
|
108
126
|
end
|
109
|
-
|
110
127
|
end
|
111
128
|
end
|
112
129
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
class RuoteKit::Application
|
3
|
+
|
4
|
+
get '/_ruote/errors/?' do
|
5
|
+
|
6
|
+
@errors = engine.errors
|
7
|
+
|
8
|
+
respond_to do |format|
|
9
|
+
format.html { haml :errors }
|
10
|
+
format.json { json( :errors, @errors ) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
get '/_ruote/errors/:wfid' do
|
15
|
+
|
16
|
+
process = engine.process( wfid )
|
17
|
+
@errors = process ? process.errors : nil
|
18
|
+
|
19
|
+
if @errors
|
20
|
+
respond_to do |format|
|
21
|
+
format.html { haml :errors }
|
22
|
+
format.json { json( :errors, @errors ) }
|
23
|
+
end
|
24
|
+
else
|
25
|
+
resource_not_found
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
get '/_ruote/errors/:wfid/:expid' do
|
30
|
+
|
31
|
+
process = engine.process( wfid )
|
32
|
+
errors = process ? process.errors : nil
|
33
|
+
@error = errors ? errors.find { |e| e.fei.expid == expid } : nil
|
34
|
+
|
35
|
+
if @error
|
36
|
+
respond_to do |format|
|
37
|
+
format.html { haml :error }
|
38
|
+
format.json { json( :error, @error ) }
|
39
|
+
end
|
40
|
+
else
|
41
|
+
resource_not_found
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# replay_at_error(e)
|
46
|
+
#
|
47
|
+
delete '/_ruote/errors/:wfid/:expid' do
|
48
|
+
|
49
|
+
#process = engine.process( params[:wfid] )
|
50
|
+
#if process && expression = process.expressions.detect { |exp| exp.fei.expid == params[:expid] }
|
51
|
+
# if params[:_kill]
|
52
|
+
# engine.kill_expression( expression.fei )
|
53
|
+
# else
|
54
|
+
# engine.cancel_expression( expression.fei )
|
55
|
+
# end
|
56
|
+
# respond_to do |format|
|
57
|
+
# format.html { redirect "/_ruote/expressions/#{params[:wfid]}" }
|
58
|
+
# format.json { json( :status, :ok ) }
|
59
|
+
# end
|
60
|
+
#else
|
61
|
+
# resource_not_found
|
62
|
+
#end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|