simianarmy-ruote-external-workitem-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.textile
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Kenneth Kalmer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,12 @@
1
+ h1. Ruote External Workitem
2
+
3
+ A thin wrapper class that facilitates the examination/altering of ruote workitem's outside of the running engine.
4
+
5
+ Example uses:
6
+
7
+ * route-rest clients
8
+ * route-kit clients
9
+ * XMPP bots (messaged through the JabberParticipant)
10
+ * AMQP bots (messaged through the AMQPParticipant)
11
+ * Nanite agents (messaged through the NaniteMasterParticipant)
12
+ * Your own external consumers!
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ruote-external-workitem-rails"
8
+ gem.summary = %Q{TODO}
9
+ gem.email = "simianarmy@gmail.com"
10
+ gem.homepage = "http://github.com/simianarmy/ruote-external-workitem"
11
+ gem.authors = ["Kenneth Kalmer", "Marc Mauger"]
12
+
13
+ # gem is a Gem::Specification... see
14
+ # http://www.rubygems.org/read/chapter/20 for additional settings
15
+ gem.add_dependency 'active_support'
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+
34
+ task :default => :spec
35
+
36
+ require 'rake/rdoctask'
37
+ Rake::RDocTask.new do |rdoc|
38
+ if File.exist?('VERSION.yml')
39
+ config = YAML.load(File.read('VERSION.yml'))
40
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
41
+ else
42
+ version = ""
43
+ end
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "ruote-external-workitem #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
50
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 0
@@ -0,0 +1,23 @@
1
+ $:.unshift( File.dirname(__FILE__) ) unless $:.include?( File.dirname(__FILE__) )
2
+
3
+ require 'rubygems'
4
+ require 'active_support'
5
+
6
+ # Provide a thin wrapper around the OpenWFE::InFlowWorkItem instances
7
+ # that eases interacting with the workitems from outside of the
8
+ # running engine.
9
+ module RuoteExternalWorkitem
10
+ autoload :Base, "ruote_external_workitem/base"
11
+ autoload :REST, "ruote_external_workitem/rest"
12
+ autoload :AMQP, "ruote_external_workitem/amqp"
13
+ autoload :XMPP, "ruote_external_workitem/xmpp"
14
+
15
+ class << self
16
+
17
+ # Parse the string representation of a OpenWFE::InFlowWorkItem
18
+ # instance from JSON
19
+ def parse( json_string )
20
+ Base.new( ActiveSupport::JSON.decode( json_string ) )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ module RuoteExternalWorkitem
2
+ # Extension to #Base with AMQP specific information exposed
3
+ module AMQP
4
+
5
+ def source_queue
6
+ @workitem['source_queue']
7
+ end
8
+
9
+ def reply_queue
10
+ @workitem['reply_queue']
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,65 @@
1
+ require 'time'
2
+
3
+ module RuoteExternalWorkitem
4
+ # Shared functionality for all workitems, no matter what the source
5
+ # of the workitem is.
6
+ class Base
7
+ include REST
8
+ include AMQP
9
+ include XMPP
10
+
11
+ def initialize( workitem = {} )
12
+ @workitem = workitem
13
+ end
14
+
15
+ def fei
16
+ @workitem['flow_expression_id']
17
+ end
18
+
19
+ def short_fei
20
+ @short_fei ||=
21
+ '(' + [
22
+ 'fei', self.fei['owfe_version'], self.fei['engine_id'],
23
+ self.fei['workflow_definition_url'], self.fei['workflow_definition_name'],
24
+ self.fei['workflow_definition_revision'], self.fei['workflow_instance_id'],
25
+ self.fei['expression_name'], self.fei['expression_id']
26
+ ].join(' ') + ')'
27
+ end
28
+
29
+ def dispatch_time
30
+ @dispath_time ||= Time.parse( @workitem['dispatch_time'] )
31
+ end
32
+
33
+ def last_modified
34
+ @last_modified ||= Time.parse( @workitem['last_modified'] )
35
+ end
36
+
37
+ def participant_name
38
+ @workitem['participant_name']
39
+ end
40
+
41
+ def attributes
42
+ @workitem['attributes']
43
+ end
44
+
45
+ def []( key )
46
+ self.attributes[ key ]
47
+ end
48
+
49
+ def []=( key, value )
50
+ self.attributes[ key ] = value
51
+ end
52
+
53
+ def to_json
54
+ ActiveSupport::JSON.encode(@workitem)
55
+ end
56
+
57
+ def method_missing( method_name, *args )
58
+ if self.attributes.keys.include?( method_name.to_s )
59
+ return self.attributes[ method_name.to_s ]
60
+ end
61
+
62
+ super
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ require 'uri'
2
+
3
+ module RuoteExternalWorkitem
4
+ # Extension of #Base that allows for accessing additional
5
+ # information from the workitems when using a RESTful interface like
6
+ # ruote-rest.
7
+ module REST
8
+
9
+ def base_uri
10
+ self.parsed_uri ? self.parsed_uri.to_s.gsub( self.parsed_uri.path, '/' ) : nil
11
+ end
12
+
13
+ def uri
14
+ self.parsed_uri ? self.parsed_uri.to_s : nil
15
+ end
16
+
17
+ def parsed_uri
18
+ @parsed_uri ||= URI.parse( @workitem['links'].detect { |l| l['rel'] == 'self' }['href'] ) rescue false
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module RuoteExternalWorkitem
2
+ # Extensions to #Base with XMPP specific information exposed
3
+ module XMPP
4
+
5
+ def source_jid
6
+ @workitem['source_jid']
7
+ end
8
+
9
+ def reply_jid
10
+ @workitem['reply_jid']
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,205 @@
1
+ require 'spec_helper'
2
+
3
+ describe RuoteExternalWorkitem, "parsing" do
4
+ it "should parse a workitem from JSON" do
5
+ json = <<-JSON
6
+ {"last_modified": "2009/04/23 12:49:07 +0200",
7
+ "type": "OpenWFE::InFlowWorkItem",
8
+ "participant_name": "toto",
9
+ "attributes": {"shallow": "true", "nes": {"ted": "yes" } },
10
+ "links": [{"href": "http://localhost:4567/workitems", "rel": "via"},
11
+ {"href": "http://localhost:4567/workitems/20090413-juduhojewo/0_0_0_0_1", "rel": "self"}],
12
+ "dispatch_time": "2009/04/23 12:49:07 +0200",
13
+ "flow_expression_id": {"workflow_definition_url": "field:__definition",
14
+ "expression_name": "toto",
15
+ "workflow_definition_name": "TestExternal",
16
+ "owfe_version": "0.9.21",
17
+ "workflow_definition_revision": "0",
18
+ "workflow_instance_id": "20090413-juduhojewo",
19
+ "engine_id": "ruote_rest",
20
+ "expression_id": "0.0.0.0.1"}}
21
+ JSON
22
+
23
+ wi = RuoteExternalWorkitem.parse( json )
24
+ wi.should be_an_instance_of( RuoteExternalWorkitem::Base )
25
+ end
26
+ end
27
+
28
+ describe RuoteExternalWorkitem::Base do
29
+ before(:each) do
30
+ json = <<-JSON
31
+ {"last_modified": "2009/04/23 12:49:07 +0200",
32
+ "type": "OpenWFE::InFlowWorkItem",
33
+ "participant_name": "toto",
34
+ "attributes": {"shallow": "true", "nes": {"ted": "yes" } },
35
+ "dispatch_time": "2009/04/23 12:49:07 +0200",
36
+ "flow_expression_id":
37
+ {"workflow_definition_url": "field:__definition",
38
+ "expression_name": "toto",
39
+ "workflow_definition_name": "TestExternal",
40
+ "owfe_version": "0.9.21",
41
+ "workflow_definition_revision": "0",
42
+ "workflow_instance_id": "20090413-juduhojewo",
43
+ "engine_id": "ruote_rest",
44
+ "expression_id": "0.0.0.0.1"}
45
+ }
46
+ JSON
47
+
48
+ @wi = RuoteExternalWorkitem.parse( json )
49
+ end
50
+
51
+ it "should have a fei (FlowExpressionId) hash" do
52
+ fei = @wi.fei
53
+
54
+ fei['owfe_version'].should == '0.9.21'
55
+
56
+ fei.keys.should include('workflow_definition_url')
57
+ fei.keys.should include('expression_name')
58
+ fei.keys.should include('owfe_version')
59
+ fei.keys.should include('workflow_definition_name')
60
+ fei.keys.should include('workflow_instance_id')
61
+ fei.keys.should include('engine_id')
62
+ fei.keys.should include('expression_id')
63
+ end
64
+
65
+ it "should have 'short fei'" do
66
+ @wi.short_fei.should == '(fei 0.9.21 ruote_rest field:__definition TestExternal 0 20090413-juduhojewo toto 0.0.0.0.1)'
67
+ end
68
+
69
+ it "should have a participant name" do
70
+ @wi.participant_name.should == 'toto'
71
+ end
72
+
73
+ it "should have a dispatch time" do
74
+ @wi.dispatch_time.should_not be_nil
75
+ @wi.dispatch_time.should be_an_instance_of( Time )
76
+ end
77
+
78
+ it "should have a last modified time" do
79
+ @wi.last_modified.should_not be_nil
80
+ @wi.last_modified.should be_an_instance_of( Time )
81
+ end
82
+
83
+ it "should have attributes" do
84
+ @wi.attributes.should be_an_instance_of( Hash )
85
+ @wi.attributes['shallow'].should be_true
86
+ end
87
+
88
+ it "should act like a hash for attributes" do
89
+ @wi['shallow'].should be_true
90
+ end
91
+
92
+ it "should have convenient access to attribute keys through methods" do
93
+ lambda {
94
+ @wi.shallow.should be_true
95
+ }.should_not raise_error(NoMethodError)
96
+ end
97
+
98
+ it "should spill itself as json" do
99
+ lambda {
100
+ ActiveSupport::JSON.decode( @wi.to_json )
101
+ }.should_not raise_error
102
+ end
103
+ end
104
+
105
+ describe RuoteExternalWorkitem::REST do
106
+ before(:each) do
107
+ json = <<-JSON
108
+ {"last_modified": "2009/04/23 12:49:07 +0200",
109
+ "type": "OpenWFE::InFlowWorkItem",
110
+ "participant_name": "toto",
111
+ "attributes": {"shallow": "true", "nes": {"ted": "yes" } },
112
+ "links": [{"href": "http://localhost:4567/workitems", "rel": "via"},
113
+ {"href": "http://localhost:4567/workitems/20090413-juduhojewo/0_0_0_0_1", "rel": "self"}],
114
+ "dispatch_time": "2009/04/23 12:49:07 +0200",
115
+ "flow_expression_id":
116
+ {"workflow_definition_url": "field:__definition",
117
+ "expression_name": "toto",
118
+ "workflow_definition_name": "TestExternal",
119
+ "owfe_version": "0.9.21",
120
+ "workflow_definition_revision": "0",
121
+ "workflow_instance_id": "20090413-juduhojewo",
122
+ "engine_id": "ruote_rest",
123
+ "expression_id": "0.0.0.0.1"}
124
+ }
125
+ JSON
126
+
127
+ @wi = RuoteExternalWorkitem.parse( json )
128
+ end
129
+
130
+ it "should have a base URI" do
131
+ @wi.base_uri.should == "http://localhost:4567/"
132
+ end
133
+
134
+ it "should have a URI to self" do
135
+ @wi.uri.should == "http://localhost:4567/workitems/20090413-juduhojewo/0_0_0_0_1"
136
+ end
137
+ end
138
+
139
+ describe RuoteExternalWorkitem::XMPP do
140
+ before(:each) do
141
+ json = <<-JSON
142
+ {"last_modified": "2009/04/23 12:49:07 +0200",
143
+ "type": "OpenWFE::InFlowWorkItem",
144
+ "participant_name": "toto",
145
+ "attributes": {"shallow": "true", "nes": {"ted": "yes" } },
146
+ "source_jid": "jabber@example.com",
147
+ "reply_jid": "replies@example.com",
148
+ "dispatch_time": "2009/04/23 12:49:07 +0200",
149
+ "flow_expression_id":
150
+ {"workflow_definition_url": "field:__definition",
151
+ "expression_name": "toto",
152
+ "workflow_definition_name": "TestExternal",
153
+ "owfe_version": "0.9.21",
154
+ "workflow_definition_revision": "0",
155
+ "workflow_instance_id": "20090413-juduhojewo",
156
+ "engine_id": "ruote_rest",
157
+ "expression_id": "0.0.0.0.1"}
158
+ }
159
+ JSON
160
+
161
+ @wi = RuoteExternalWorkitem.parse( json )
162
+ end
163
+
164
+ it "should have a source jabber id" do
165
+ @wi.source_jid.should == 'jabber@example.com'
166
+ end
167
+
168
+ it "should have a destination jabber id for replies" do
169
+ @wi.reply_jid.should == 'replies@example.com'
170
+ end
171
+ end
172
+
173
+ describe RuoteExternalWorkitem::AMQP do
174
+ before(:each) do
175
+ json = <<-JSON
176
+ {"last_modified": "2009/04/23 12:49:07 +0200",
177
+ "type": "OpenWFE::InFlowWorkItem",
178
+ "participant_name": "toto",
179
+ "attributes": {"shallow": "true", "nes": {"ted": "yes" } },
180
+ "source_queue": "ruote.participant",
181
+ "reply_queue": "ruote.listener",
182
+ "dispatch_time": "2009/04/23 12:49:07 +0200",
183
+ "flow_expression_id":
184
+ {"workflow_definition_url": "field:__definition",
185
+ "expression_name": "toto",
186
+ "workflow_definition_name": "TestExternal",
187
+ "owfe_version": "0.9.21",
188
+ "workflow_definition_revision": "0",
189
+ "workflow_instance_id": "20090413-juduhojewo",
190
+ "engine_id": "ruote_rest",
191
+ "expression_id": "0.0.0.0.1"}
192
+ }
193
+ JSON
194
+
195
+ @wi = RuoteExternalWorkitem.parse( json )
196
+ end
197
+
198
+ it "should have a source queue" do
199
+ @wi.source_queue.should == 'ruote.participant'
200
+ end
201
+
202
+ it "should have a queue name for replies" do
203
+ @wi.reply_queue.should == 'ruote.listener'
204
+ end
205
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'ruote_external_workitem'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simianarmy-ruote-external-workitem-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kenneth Kalmer
8
+ - Marc Mauger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-07-12 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: active_support
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ description:
27
+ email: simianarmy@gmail.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - LICENSE
34
+ - README.textile
35
+ files:
36
+ - .document
37
+ - LICENSE
38
+ - README.textile
39
+ - Rakefile
40
+ - VERSION.yml
41
+ - lib/ruote_external_workitem.rb
42
+ - lib/ruote_external_workitem/amqp.rb
43
+ - lib/ruote_external_workitem/base.rb
44
+ - lib/ruote_external_workitem/rest.rb
45
+ - lib/ruote_external_workitem/xmpp.rb
46
+ - spec/ruote_external_workitem_spec.rb
47
+ - spec/spec_helper.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/simianarmy/ruote-external-workitem
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.2.0
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: TODO
74
+ test_files:
75
+ - spec/ruote_external_workitem_spec.rb
76
+ - spec/spec_helper.rb