agent_xmpp 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.
Files changed (73) hide show
  1. data/.document +5 -0
  2. data/.gitignore +11 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +417 -0
  5. data/Rakefile +75 -0
  6. data/VERSION +1 -0
  7. data/agent_xmpp.gemspec +144 -0
  8. data/lib/agent_xmpp.rb +22 -0
  9. data/lib/agent_xmpp/admin.rb +113 -0
  10. data/lib/agent_xmpp/client.rb +7 -0
  11. data/lib/agent_xmpp/client/boot.rb +83 -0
  12. data/lib/agent_xmpp/client/client.rb +64 -0
  13. data/lib/agent_xmpp/client/connection.rb +108 -0
  14. data/lib/agent_xmpp/client/controller.rb +394 -0
  15. data/lib/agent_xmpp/client/message_delegate.rb +720 -0
  16. data/lib/agent_xmpp/client/message_pipe.rb +193 -0
  17. data/lib/agent_xmpp/client/response.rb +102 -0
  18. data/lib/agent_xmpp/config.rb +48 -0
  19. data/lib/agent_xmpp/main.rb +175 -0
  20. data/lib/agent_xmpp/models.rb +7 -0
  21. data/lib/agent_xmpp/models/contact.rb +85 -0
  22. data/lib/agent_xmpp/models/message.rb +152 -0
  23. data/lib/agent_xmpp/models/publication.rb +53 -0
  24. data/lib/agent_xmpp/models/roster.rb +107 -0
  25. data/lib/agent_xmpp/models/service.rb +91 -0
  26. data/lib/agent_xmpp/models/subscription.rb +61 -0
  27. data/lib/agent_xmpp/models/table_definitions.rb +107 -0
  28. data/lib/agent_xmpp/patches.rb +7 -0
  29. data/lib/agent_xmpp/patches/array.rb +32 -0
  30. data/lib/agent_xmpp/patches/float.rb +10 -0
  31. data/lib/agent_xmpp/patches/hash.rb +13 -0
  32. data/lib/agent_xmpp/patches/object.rb +15 -0
  33. data/lib/agent_xmpp/patches/rexml.rb +69 -0
  34. data/lib/agent_xmpp/patches/string.rb +15 -0
  35. data/lib/agent_xmpp/xmpp.rb +18 -0
  36. data/lib/agent_xmpp/xmpp/element.rb +158 -0
  37. data/lib/agent_xmpp/xmpp/entry.rb +36 -0
  38. data/lib/agent_xmpp/xmpp/error_response.rb +189 -0
  39. data/lib/agent_xmpp/xmpp/iq.rb +90 -0
  40. data/lib/agent_xmpp/xmpp/iq_command.rb +54 -0
  41. data/lib/agent_xmpp/xmpp/iq_disco.rb +206 -0
  42. data/lib/agent_xmpp/xmpp/iq_pubsub.rb +270 -0
  43. data/lib/agent_xmpp/xmpp/iq_roster.rb +183 -0
  44. data/lib/agent_xmpp/xmpp/iq_version.rb +89 -0
  45. data/lib/agent_xmpp/xmpp/jid.rb +150 -0
  46. data/lib/agent_xmpp/xmpp/message.rb +82 -0
  47. data/lib/agent_xmpp/xmpp/presence.rb +127 -0
  48. data/lib/agent_xmpp/xmpp/sasl.rb +241 -0
  49. data/lib/agent_xmpp/xmpp/stanza.rb +107 -0
  50. data/lib/agent_xmpp/xmpp/x_data.rb +357 -0
  51. data/test/app/app.rb +339 -0
  52. data/test/cases/test_application_message_processing.rb +65 -0
  53. data/test/cases/test_errors.rb +24 -0
  54. data/test/cases/test_presence_management.rb +139 -0
  55. data/test/cases/test_roster_management.rb +214 -0
  56. data/test/cases/test_service_discovery.rb +168 -0
  57. data/test/cases/test_session_management.rb +120 -0
  58. data/test/cases/test_version_discovery.rb +67 -0
  59. data/test/helpers/matchers.rb +23 -0
  60. data/test/helpers/mocks.rb +82 -0
  61. data/test/helpers/test_case_extensions.rb +45 -0
  62. data/test/helpers/test_client.rb +44 -0
  63. data/test/helpers/test_delegate.rb +60 -0
  64. data/test/helpers/test_helper.rb +91 -0
  65. data/test/messages/application_messages.rb +206 -0
  66. data/test/messages/error_messages.rb +35 -0
  67. data/test/messages/presence_messages.rb +66 -0
  68. data/test/messages/roster_messages.rb +126 -0
  69. data/test/messages/service_discovery_messages.rb +201 -0
  70. data/test/messages/session_messages.rb +158 -0
  71. data/test/messages/version_discovery_messages.rb +69 -0
  72. data/test/peer/peer.rb +21 -0
  73. metadata +187 -0
@@ -0,0 +1,270 @@
1
+ # Original from XMPP4R - XMPP Library for Ruby Website::http://home.gna.org/xmpp4r/
2
+ ##############################################################################################################
3
+ module AgentXmpp
4
+
5
+ #####-------------------------------------------------------------------------------------------------------
6
+ module Xmpp
7
+
8
+ #####-------------------------------------------------------------------------------------------------------
9
+ class IqPubSub < Element
10
+
11
+ #.......................................................................................................
12
+ name_xmlns 'pubsub', 'http://jabber.org/protocol/pubsub'
13
+ xmpp_child :subscription, :publish
14
+
15
+ #####-------------------------------------------------------------------------------------------------------
16
+ class << self
17
+
18
+ #.........................................................................................................
19
+ def create_node(pipe, to, node)
20
+ iq = Xmpp::Iq.new(:set, to)
21
+ create = REXML::Element.new('create')
22
+ create.add_attribute('node', node)
23
+ iq.pubsub = IqPubSub.new << create
24
+ configure = REXML::Element.new('configure')
25
+ user_config = Publication.find_by_node(node)
26
+ if user_config
27
+ form = Xmpp::XData.new(:submit)
28
+ form.add_field_with_value('FORM_TYPE', 'http://jabber.org/protocol/pubsub#node_config', :hidden)
29
+ configure << AgentXmpp::DEFAULT_PUBSUB_CONFIG.inject(form) do |f, (var, val)|
30
+ f.add_field_with_value("pubsub##{var.to_s}", user_config.send(var) || val)
31
+ end
32
+ end
33
+ iq.pubsub << configure
34
+ Send(iq) do |r|
35
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
36
+ pipe.broadcast_to_delegates(:on_pubsub_create_node_result, pipe, r, node)
37
+ elsif r.type.eql?(:error)
38
+ pipe.broadcast_to_delegates(:on_pubsub_create_node_error, pipe, r, node)
39
+ end
40
+ end
41
+ end
42
+
43
+ #.........................................................................................................
44
+ def subscriptions(pipe, to)
45
+ iq = Xmpp::Iq.new(:get, to)
46
+ iq.pubsub = IqPubSub.new << REXML::Element.new('subscriptions')
47
+ Send(iq) do |r|
48
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
49
+ pipe.broadcast_to_delegates(:on_pubsub_subscriptions_result, pipe, r)
50
+ elsif r.type.eql?(:error)
51
+ pipe.broadcast_to_delegates(:on_pubsub_subscriptions_error, pipe, r)
52
+ end
53
+ end
54
+ end
55
+
56
+ #.........................................................................................................
57
+ def subscribe(pipe, to, node)
58
+ iq = Xmpp::Iq.new(:set, to)
59
+ subscribe = REXML::Element.new('subscribe')
60
+ subscribe.add_attribute('node', node)
61
+ subscribe.add_attribute('jid', AgentXmpp.jid.bare.to_s)
62
+ iq.pubsub = IqPubSub.new << subscribe
63
+ Send(iq) do |r|
64
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
65
+ pipe.broadcast_to_delegates(:on_pubsub_subscribe_result, pipe, r, node)
66
+ elsif r.type.eql?(:error)
67
+ pipe.broadcast_to_delegates(:on_pubsub_subscribe_error, pipe, r, node)
68
+ end
69
+ end
70
+ end
71
+
72
+ #.........................................................................................................
73
+ def unsubscribe(pipe, to, node)
74
+ iq = Xmpp::Iq.new(:set, to)
75
+ unsubscribe = REXML::Element.new('unsubscribe')
76
+ unsubscribe.add_attribute('node', node)
77
+ unsubscribe.add_attribute('jid', AgentXmpp.jid.bare.to_s)
78
+ iq.pubsub = IqPubSub.new << unsubscribe
79
+ Send(iq) do |r|
80
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
81
+ pipe.broadcast_to_delegates(:on_pubsub_unsubscribe_result, pipe, r, node)
82
+ elsif r.type.eql?(:error)
83
+ pipe.broadcast_to_delegates(:on_pubsub_unsubscribe_error, pipe, r, node)
84
+ end
85
+ end
86
+ end
87
+
88
+ #.........................................................................................................
89
+ def affiliations(pipe, to)
90
+ iq = Xmpp::Iq.new(:get, to)
91
+ iq.pubsub = IqPubSub.new << REXML::Element.new('affiliations')
92
+ Send(iq) do |r|
93
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
94
+ pipe.broadcast_to_delegates(:on_pubsub_affiliations_result, pipe, r)
95
+ elsif r.type.eql?(:error)
96
+ pipe.broadcast_to_delegates(:on_pubsub_affiliations_error, pipe, r)
97
+ end
98
+ end
99
+ end
100
+
101
+ #### self
102
+ end
103
+
104
+ #.........................................................................................................
105
+ def subscriptions
106
+ first_element('subscriptions').elements.to_a('subscription')
107
+ end
108
+
109
+ #### IqPubSub
110
+ end
111
+
112
+ #####--------------------------------------------------------------------------------------------------------
113
+ class IqPubSubOwner < Element
114
+
115
+ #..........................................................................................................
116
+ name_xmlns 'pubsub', 'http://jabber.org/protocol/pubsub' + '#owner'
117
+
118
+ #####-------------------------------------------------------------------------------------------------------
119
+ class << self
120
+
121
+ #.........................................................................................................
122
+ def delete_node(pipe, to, node)
123
+ iq = Xmpp::Iq.new(:set, to)
124
+ delete = REXML::Element.new('delete')
125
+ delete.add_attribute('node', node)
126
+ iq.pubsub = IqPubSubOwner.new << delete
127
+ Send(iq) do |r|
128
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
129
+ pipe.broadcast_to_delegates(:on_pubsub_delete_node_result, pipe, r, node)
130
+ elsif r.type.eql?(:error)
131
+ pipe.broadcast_to_delegates(:on_pubsub_delete_node_error, pipe, r, node)
132
+ end
133
+ end
134
+ end
135
+
136
+ #### self
137
+ end
138
+
139
+ end
140
+
141
+ #####-------------------------------------------------------------------------------------------------------
142
+ class IqPublish < Element
143
+
144
+ #.........................................................................................................
145
+ name_xmlns 'publish', 'http://jabber.org/protocol/pubsub'
146
+ xmpp_attribute :node
147
+ xmpp_child :item
148
+
149
+ #####-------------------------------------------------------------------------------------------------------
150
+ class << self
151
+
152
+ #.........................................................................................................
153
+ def set(pipe, args)
154
+ iq = Xmpp::Iq.new(:set, args[:to])
155
+ item = Item.new << args[:payload]
156
+ pub = IqPublish.new("#{AgentXmpp.user_pubsub_root}/#{args[:node]}") << item
157
+ iq.pubsub = IqPubSub.new << pub
158
+ Send(iq) do |r|
159
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
160
+ pipe.broadcast_to_delegates(:on_publish_result, pipe, r, args[:node])
161
+ elsif r.type.eql?(:error)
162
+ pipe.broadcast_to_delegates(:on_publish_error, pipe, r, args[:node])
163
+ end
164
+ end
165
+ end
166
+
167
+ #### self
168
+ end
169
+
170
+ #.........................................................................................................
171
+ def initialize(node=nil)
172
+ super()
173
+ self.node = node if node
174
+ end
175
+ end
176
+
177
+ #####-------------------------------------------------------------------------------------------------------
178
+ class Items < Element
179
+ name_xmlns 'items', 'http://jabber.org/protocol/pubsub'
180
+ xmpp_attribute :node, :subid, :max_items
181
+ end
182
+
183
+ #####-------------------------------------------------------------------------------------------------------
184
+ class Item < Element
185
+ name_xmlns 'item', 'http://jabber.org/protocol/pubsub'
186
+ xmpp_attribute :id
187
+ xmpp_child :x, :entry
188
+ def initialize(id=nil)
189
+ super()
190
+ self.id = id if id
191
+ end
192
+ end
193
+
194
+ #####-------------------------------------------------------------------------------------------------------
195
+ class Event < Element
196
+ name_xmlns 'event', 'http://jabber.org/protocol/pubsub' + "#event"
197
+ def items
198
+ elements.to_a('items')
199
+ end
200
+ end
201
+
202
+ #####-------------------------------------------------------------------------------------------------------
203
+ class EventItems < Items
204
+ name_xmlns 'items', 'http://jabber.org/protocol/pubsub' + "#event"
205
+ #.........................................................................................................
206
+ def item
207
+ elements.to_a('item')
208
+ end
209
+ end
210
+
211
+ #####-------------------------------------------------------------------------------------------------------
212
+ class EventItem < Item
213
+ name_xmlns 'item', 'http://jabber.org/protocol/pubsub' + "#event"
214
+ end
215
+
216
+ #####-------------------------------------------------------------------------------------------------------
217
+ class Subscriptions < Element
218
+ name_xmlns 'subscriptions', 'http://jabber.org/protocol/pubsub'
219
+ end
220
+
221
+ #####-------------------------------------------------------------------------------------------------------
222
+ class Subscription < Element
223
+
224
+ #.........................................................................................................
225
+ name_xmlns 'subscription', 'http://jabber.org/protocol/pubsub'
226
+ xmpp_attribute :node, :subid, :subscription
227
+
228
+ #.........................................................................................................
229
+ def initialize(jid=nil, node=nil, subid=nil, state=nil)
230
+ super()
231
+ self.jid = jid if jid
232
+ self.node = node if node
233
+ self.subid = subid if subid
234
+ self.state = state if state
235
+ end
236
+
237
+ #.........................................................................................................
238
+ def jid
239
+ (a = attribute('jid')).nil? ? a : Jid.new(a.value)
240
+ end
241
+
242
+ #.........................................................................................................
243
+ def jid=(myjid)
244
+ add_attribute('jid', myjid ? myjid.to_s : nil)
245
+ end
246
+
247
+ #.........................................................................................................
248
+ def state
249
+ sub = attributes['subscription']
250
+ ['none', 'pending', 'subscribed', 'unconfigured'].include?(sub) ? sub.to_sym : nil
251
+ end
252
+
253
+ #.........................................................................................................
254
+ def state=(mystate)
255
+ attributes['subscription'] = mystate
256
+ end
257
+
258
+ #.........................................................................................................
259
+ def need_approval?
260
+ state == :pending
261
+ end
262
+
263
+ #### Subscription
264
+ end
265
+
266
+ #### Xmpp
267
+ end
268
+
269
+ #### AgentXmpp
270
+ end
@@ -0,0 +1,183 @@
1
+ # Original from XMPP4R - XMPP Library for Ruby Website::http://home.gna.org/xmpp4r/
2
+ ##############################################################################################################
3
+ module AgentXmpp
4
+
5
+ #####-------------------------------------------------------------------------------------------------------
6
+ module Xmpp
7
+
8
+ #####-------------------------------------------------------------------------------------------------------
9
+ class IqRoster < IqQuery
10
+
11
+ #.......................................................................................................
12
+ name_xmlns 'query', 'jabber:iq:roster'
13
+
14
+ #####-------------------------------------------------------------------------------------------------------
15
+ class << self
16
+
17
+ #.........................................................................................................
18
+ def get(pipe)
19
+ Send(new_rosterget) do |r|
20
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
21
+ pipe.broadcast_to_delegates(:on_roster_result, pipe, r)
22
+ elsif r.type.eql?(:error)
23
+ raise AgentXmppError, "roster request failed"
24
+ end
25
+ end
26
+ end
27
+
28
+ #.........................................................................................................
29
+ def update(pipe, roster_item_jid, groups=nil)
30
+ request = new_rosterset
31
+ item = Xmpp::RosterItem.new(roster_item_jid)
32
+ item.groups = groups unless groups.nil?
33
+ request.query.add(item)
34
+ Send(request) do |r|
35
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
36
+ pipe.broadcast_to_delegates(:on_update_roster_item_result, pipe, roster_item_jid)
37
+ elsif r.type.eql?(:error)
38
+ pipe.broadcast_to_delegates(:on_update_roster_item_error, pipe, roster_item_jid)
39
+ end
40
+ end
41
+ end
42
+
43
+ #.........................................................................................................
44
+ def remove(pipe, roster_item_jid)
45
+ request = new_rosterset
46
+ request.query.add(Xmpp::RosterItem.new(roster_item_jid, nil, :remove))
47
+ Send(request) do |r|
48
+ if r.type == :result and r.kind_of?(Xmpp::Iq)
49
+ pipe.broadcast_to_delegates(:on_remove_roster_item_result, pipe, roster_item_jid)
50
+ elsif r.type.eql?(:error)
51
+ pipe.broadcast_to_delegates(:on_remove_roster_item_error, pipe, roster_item_jid)
52
+ end
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ #.......................................................................................................
59
+ def new_rosterget
60
+ iq = Iq.new(:get)
61
+ query = IqQuery.new
62
+ query.add_namespace('jabber:iq:roster')
63
+ iq.add(query)
64
+ iq
65
+ end
66
+
67
+ #.......................................................................................................
68
+ def new_rosterset
69
+ iq = Iq.new(:set)
70
+ query = IqQuery.new
71
+ query.add_namespace('jabber:iq:roster')
72
+ iq.add(query)
73
+ iq
74
+ end
75
+
76
+ #### self
77
+ end
78
+
79
+ #.......................................................................................................
80
+ def each(&block)
81
+ each_element {|item| yield(item) if item.kind_of?(RosterItem)}
82
+ end
83
+
84
+ #.......................................................................................................
85
+ def [](jid)
86
+ each{|item| return(item) if item.jid == jid}
87
+ nil
88
+ end
89
+
90
+ #.......................................................................................................
91
+ def to_a
92
+ a = []
93
+ each{|item| a.push(item)}
94
+ a
95
+ end
96
+
97
+ #.......................................................................................................
98
+ def receive_iq(iq, filter=true)
99
+ return if filter && (((iq.type != :set) && (iq.type != :result)) || (iq.queryns != 'jabber:iq:roster'))
100
+ import(iq.query)
101
+ end
102
+
103
+ #.......................................................................................................
104
+ def inspect
105
+ jids = to_a.collect { |item| item.jid.inspect }
106
+ jids.join(', ')
107
+ end
108
+
109
+ #### IqQueryRoster
110
+ end
111
+
112
+ #####-------------------------------------------------------------------------------------------------------
113
+ class RosterItem < Element
114
+
115
+ #.......................................................................................................
116
+ name_xmlns 'item', 'jabber:iq:roster'
117
+ xmpp_attribute :subscription, :sym => true
118
+
119
+ #.......................................................................................................
120
+ def initialize(jid=nil, iname=nil, subscription=nil, ask=nil)
121
+ super()
122
+ self.jid = jid
123
+ self.iname = iname if iname
124
+ self.subscription = subscription if subscription
125
+ self.ask = ask if ask
126
+ end
127
+
128
+ #.......................................................................................................
129
+ def iname
130
+ attributes['name']
131
+ end
132
+
133
+ #.......................................................................................................
134
+ def iname=(val)
135
+ attributes['name'] = val
136
+ end
137
+
138
+ #.......................................................................................................
139
+ def jid
140
+ (a = attributes['jid']) ? Jid.new(a) : nil
141
+ end
142
+
143
+ #.......................................................................................................
144
+ def jid=(val)
145
+ attributes['jid'] = val.nil? ? nil : val.to_s
146
+ end
147
+
148
+ #.......................................................................................................
149
+ def ask
150
+ case attributes['ask']
151
+ when 'subscribe' then :subscribe
152
+ else :none
153
+ end
154
+ end
155
+
156
+ #.......................................................................................................
157
+ def ask=(val)
158
+ case val
159
+ when :subscribe then attributes['ask'] = 'subscribe'
160
+ else attributes['ask'] = nil
161
+ end
162
+ end
163
+
164
+ #.......................................................................................................
165
+ def groups
166
+ elements.inject('group', []) {|r, g| r << g.text}.uniq
167
+ end
168
+
169
+ #.......................................................................................................
170
+ def groups=(ary)
171
+ delete_elements('group')
172
+ ary.uniq.each{|group| add_element('group').text = group}
173
+ end
174
+
175
+ #### RosterItem
176
+ end
177
+
178
+ #### XMPP
179
+ end
180
+
181
+ #### AgentXmpp
182
+ end
183
+