ruote-kit 2.1.8.2 → 2.1.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|