simianarmy-ruote-external-workitem-rails 0.1.0

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/.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