agent_xmpp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,11 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage/*
4
+ rdoc/*
5
+ *.gem
6
+ *.tmproj
7
+ *.yml
8
+ *.db
9
+ log/*
10
+ *.log
11
+ test/xml_messages.txt
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Troy Stribling
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.
@@ -0,0 +1,417 @@
1
+ = Agent XMPP
2
+
3
+ Agent XMPP is a simple DSL for writing automated XMPP clients that support Messaging, Ad-Hoc Commands and Publish Subscribe
4
+ Events. An application that responds to an Ad-Hoc command can be written with few lines of code.
5
+
6
+ # myapp.rb
7
+ require 'rubygems'
8
+ require 'agent_xmpp'
9
+
10
+ command 'hello' do
11
+ 'Hello World'
12
+ end
13
+
14
+ Specify the application Jabber ID (JID), password and roster in <tt>agent_xmpp.yml</tt>.
15
+
16
+ jid: myapp@nowhere.com
17
+ password: none
18
+ roster:
19
+ -
20
+ jid:you@home.com
21
+ groups: [admin]
22
+
23
+ Be sure libxml2 headers are available and that libsqlite3-ruby1.9.1 is installed,
24
+
25
+ sudo apt-get install libxml2-dev
26
+ sudo apt-get install libsqlite3-ruby1.9.1
27
+
28
+ Install the gem,
29
+
30
+ sudo gem install troystribling-agent_xmpp --source=http://gems.github.com
31
+
32
+ Install the Gajim XMPP Client version 0.12.3 or higher, http://www.gajim.org, and connect to <i>you@home.com</i>.
33
+
34
+ Run the application,
35
+
36
+ ruby myapp.rb
37
+
38
+ When started for the first time <tt>myapp.rb</tt> will automatically send buddy requests to all contacts specified
39
+ in <tt>agent_xmpp.yml</tt>. Accept the buddy request and _myapp_ will appear as a contact in the Gajim roster. Right click on _myapp_
40
+ and select _execute_ _commands_ from the drop down menu. A list of Ad-Hoc Commands will be displayed containing _hello_.
41
+ Select it and click the _forward_ _button_ to execute.
42
+
43
+ == Supported Environment
44
+
45
+ The following versions of ruby are supported
46
+
47
+ ruby 1.9.1
48
+
49
+ The following Operating Systems are supported
50
+
51
+ Ubuntu 10.4
52
+
53
+ == Ad-Hoc Command Response Payload
54
+
55
+ Agent XMPP will map native ruby scalars, arrays and hashes returned by <tt>execute</tt> blocks to jabber:x:data command
56
+ response payloads (see XEP-0004 http://xmpp.org/extensions/xep-0004.html for a description of jabber:x:data).
57
+
58
+ command 'scalar' do
59
+ 'scalar'
60
+ end
61
+
62
+ command 'hash' do
63
+ {:a1 => 'v1', :a2 => 'v2'}
64
+ end
65
+
66
+ command 'scalar_array' do
67
+ ['v1', 'v2','v3', 'v4']
68
+ end
69
+
70
+ command 'hash_array' do
71
+ {:a1 => ['v11', 'v11'], :a2 => 'v12'}
72
+ end
73
+
74
+ command 'array_hash' do
75
+ [{:a1 => 'v11', :a2 => 'v12'},
76
+ {:a1 => 'v21', :a2 => 'v22'},
77
+ {:a1 => 'v31', :a2 => 'v32'}]
78
+ end
79
+
80
+ command 'array_hash_array' do
81
+ [{:a1 => ['v11', 'v11'], :a2 => 'v12'},
82
+ {:a1 => ['v21', 'v21'], :a2 => 'v22'},
83
+ {:a1 => ['v31', 'v31'], :a2 => 'v32'}]
84
+ end
85
+
86
+ a <tt>params</tt> structure is available within the <tt>execute</tt> block containing routing information.
87
+
88
+ == Ad-Hoc Command Forms
89
+
90
+ Agent XMPP supports
91
+ == Send Commands
92
+
93
+ Commands may be sent with or without a response callback,
94
+
95
+ send_command(:to=>'thatapp@a-place.com/ahost', :node=> 'hello') do |status, data|
96
+ puts "COMMAND RESPONSE: #{status}, #{data.inspect}"
97
+ end
98
+
99
+ send_command(:to=>'thatapp@a-place.com/ahost', :node=> 'bye')
100
+
101
+ and within <tt>command</tt> blocks.
102
+
103
+ command 'hash_hello' do
104
+ send_command(:to=>params[:from], :node=> 'hello') do |status, data|
105
+ puts "COMMAND RESPONSE: #{status}, #{data.inspect}"
106
+ end
107
+ {:a1 => 'v1', :a2 => 'v2'}
108
+ end
109
+
110
+ == Publish
111
+
112
+ Publish nodes are configured in <tt>agent_xmpp.yml</tt>.
113
+
114
+ jid: myapp@nowhere.com
115
+ password: none
116
+ roster:
117
+ -
118
+ jid:you@home.com
119
+ publish:
120
+ -
121
+ node: time
122
+ title: "Curent Time"
123
+ -
124
+ node: alarm
125
+ title: "Alarms"
126
+
127
+ The nodes are created if they do not exist and publish methods are generated for each node.
128
+
129
+ publish_time('The time is:' + Time.now.to_s)
130
+
131
+ publish_alarm({:severity => :major, :description => "A really bad failure"})
132
+
133
+ Publish nodes discovered that are not in <tt>agent_xmpp.yml</tt> will be deleted.
134
+
135
+ == Publish Options
136
+
137
+ The following publish options are available with the indicated default values. The options may be changed in
138
+ <tt>agent_xmpp.yml</tt>.
139
+
140
+ :title => 'event',
141
+ :access_model => 'presence',
142
+ :max_items => 20,
143
+ :deliver_notifications => 1,
144
+ :deliver_payloads => 1,
145
+ :persist_items => 1,
146
+ :subscribe => 1,
147
+ :notify_config => 0,
148
+ :notify_delete => 0,
149
+ :notify_retract => 0,
150
+
151
+ See http://xmpp.org/extensions/xep-0060.html#registrar-formtypes-config for a detailed description.
152
+
153
+ == Subscribe
154
+
155
+ Declare <tt>event</tt> blocks in <tt>myapp.rb</tt> to subscribe to published events.
156
+
157
+ # myapp.rb
158
+ require 'rubygems'
159
+ require 'agent_xmpp'
160
+
161
+ event 'someone@somewhere.com', 'time' do
162
+ message(:to=>'someone@somewhere.com', :body=>"Got the event at: " + Time.now.to_s)
163
+ end
164
+
165
+ Agent XMPP will verify subscription to the event and subscribe if required. Subscriptions
166
+ discovered that are not declared by an event block will be deleted.
167
+
168
+ == Receive Chat Messages
169
+
170
+ Declare <tt>chat</tt> blocks in <tt>myapp.rb</tt> to receive and respond to chat messages.
171
+
172
+ # myapp.rb
173
+ require 'rubygems'
174
+ require 'agent_xmpp'
175
+
176
+ chat do
177
+ params[:body].reverse
178
+ end
179
+
180
+ If the <tt>chat</tt> block returns a <tt>String</tt> a response will be sent to the message sender.
181
+
182
+ == Send Chat Messages
183
+
184
+ send_chat(:to=>'thatapp@a-place.com/onahost', :body=>"Hello from #{AgentXmpp.jid.to_s} at " + Time.now.to_s)
185
+
186
+ == Roster
187
+
188
+ Roster groups may be specified in <tt>agent_xmpp.yml</tt>.
189
+
190
+ jid: myapp@nowhere.com
191
+ password: none
192
+ roster:
193
+ -
194
+ jid:you@home.com
195
+ groups: [good group, owners]
196
+
197
+ -
198
+ jid: someone@somewhere.com
199
+ groups: [bad group]
200
+
201
+ Agent XMPP will update the roster maintained on the XMPP server to be consistent with to the roster specified in <tt>agent_xmpp.yml</tt>.
202
+
203
+ == Routing Priority
204
+
205
+ The routing priority may be configured in <tt>agent_xmpp.yml</tt>. The default value is 1. Valid values are between -127 and 128.
206
+ See http://xmpp.org/rfcs/rfc3921.html for a details.
207
+
208
+ jid: myapp@nowhere.com
209
+ password: none
210
+ priority: 128
211
+ roster:
212
+ -
213
+ jid:you@home.com
214
+ groups: [good group, owners]
215
+
216
+ == Major Event Callbacks
217
+
218
+ Agent XMPP provides callbacks for applications to respond to major events that occur during execution.
219
+
220
+ # application starting
221
+ before_start{}
222
+
223
+ # connected to server
224
+ after_connected{|connection|}
225
+
226
+ # client restarts when disconnected form server
227
+ restarting_client{|connection|}
228
+
229
+ # a pubsub node was discovered at service
230
+ discovered_pubsub_node{|service, node|}
231
+
232
+ # command nodes were discovered at jid
233
+ discovered_command_nodes{|jid, nodes|}
234
+
235
+ # a presence message of status :available or :unavailable was received from jid
236
+ received_presence{|from, status|}
237
+
238
+ == Authentication
239
+
240
+ * Basic SASL
241
+
242
+ == Development with XMPP Clients
243
+
244
+ Ad-Hoc Commands, jabber:x:data Forms nor Service Discovery are widely supported by XMPP clients and I have not found
245
+ a client that supports Publish-Subscribe. Gajim http://www.gajim.org provides support for Ad-Hoc Commands and jabber:x:data Forms. Service Discovery,
246
+ which is useful for Publish-Subscibe development, is supported by Gajim, but Psi http://psi-im.org provides a much better
247
+ implementation. Both Gajim and Psi provide an interface for manual entry of XML messages. Since Publish-Subscribe is not supported on
248
+ the user interface manual entry of messages is required for development. Example messages can be found at http://gist.github.com/160344
249
+
250
+ == Logging
251
+
252
+ By default log messages are written to STDOUT. A log file can be specified with the -l option.
253
+
254
+ ruby mybot.rb -l file.log
255
+
256
+ The logger can be accessed and configured.
257
+
258
+ before_start do
259
+ AgentXmpp.logger.level = Logger::WARN
260
+ end
261
+
262
+ == More Examples
263
+
264
+ More examples can be found at http://gist.github.com/160338
265
+
266
+ == Supported XEPs
267
+
268
+ XEP-0004 jabber:x:data Forms http://xmpp.org/extensions/xep-0004.html
269
+ XEP-0030 Service Discovery http://xmpp.org/extensions/xep-0030.html
270
+ XEP-0050 Ad-Hoc Commands http://xmpp.org/extensions/xep-0050.html
271
+ XEP-0060 Publish Subscribe http://xmpp.org/extensions/xep-0060.html
272
+ XEP-0092 Software Version http://xmpp.org/extensions/xep-0092.html
273
+
274
+ == Message Processing Callbacks
275
+
276
+ Message processing callbacks are available to applications to extend the message processing work flow. To receive
277
+ callbacks a delegate object must be provided that implements the callbacks of interest.
278
+
279
+ after_connected do |connection|
280
+ connection.add_delegate(YourDelegate)
281
+ end
282
+
283
+ === Connection
284
+
285
+ on_connect(connection)
286
+
287
+ on_disconnect(connection)
288
+
289
+ on_did_not_connect(connection)
290
+
291
+ === Authentication
292
+
293
+ on_bind(connection)
294
+
295
+ on_preauthenticate_features(connection)
296
+
297
+ on_authenticate(connection)
298
+
299
+ on_did_not_authenticate(connection)
300
+
301
+ on_postauthenticate_features(connection)
302
+
303
+ on_start_session(connection)
304
+
305
+ === Presence
306
+
307
+ on_presence(connection, presence)
308
+
309
+ on_presence_subscribe(connection, presence)
310
+
311
+ on_presence_subscribed(connection, presence)
312
+
313
+ on_presence_unavailable(connection, presence)
314
+
315
+ on_presence_unsubscribed(connection, presence)
316
+
317
+ on_presence_error(pipe, presence)
318
+
319
+ === Roster
320
+
321
+ on_roster_result(connection, stanza)
322
+
323
+ on_roster_set(connection, stanza)
324
+
325
+ on_roster_item(connection, roster_item)
326
+
327
+ on_remove_roster_item(connection, roster_item)
328
+
329
+ on_all_roster_items(connection)
330
+
331
+ on_update_roster_item_result(connection, item_jid)
332
+
333
+ on_update_roster_item_error(connection, item_jid)
334
+
335
+ on_remove_roster_item(connection, item_jid)
336
+
337
+ on_remove_roster_item_error(connection, item_jid)
338
+
339
+ === Service Discovery
340
+
341
+ on_version_result(connection, version)
342
+
343
+ on_version_get(connection, request)
344
+
345
+ on_version_error(connection, error)
346
+
347
+ on_discoinfo_get(connection, request)
348
+
349
+ on_discoinfo_result(connection, discoinfo)
350
+
351
+ on_discoinfo_error(connection, error)
352
+
353
+ on_discoitems_result(connection, discoitems)
354
+
355
+ on_discoitems_get(connection, request)
356
+
357
+ on_discoitems_error(connection, result)
358
+
359
+ === Applications
360
+
361
+ on_command_set(connection, stanza)
362
+
363
+ on_message_chat(connection, stanza)
364
+
365
+ on_message_normal(connection, stanza)
366
+
367
+ on_pubsub_event(connection, event, to, from)
368
+
369
+ === PubSub
370
+
371
+ on_publish_result(connection, result, node)
372
+
373
+ on_publish_error(connection, result, node)
374
+
375
+ on_discovery_of_pubsub_service(connection, jid, ident)
376
+
377
+ on_discovery_of_pubsub_collection(connection, jid, node)
378
+
379
+ on_discovery_of_pubsub_leaf(connection, jid, node)
380
+
381
+ on_discovery_of_user_pubsub_root(pipe, pubsub, node)
382
+
383
+ on_pubsub_subscriptions_result(connection, result)
384
+
385
+ on_pubsub_subscriptions_error(connection, result)
386
+
387
+ on_pubsub_affiliations_result(connection, result)
388
+
389
+ on_pubsub_affiliations_error(connection, result)
390
+
391
+ on_discovery_of_user_pubsub_root(connection, result)
392
+
393
+ on_create_node_result(connection, node, result)
394
+
395
+ on_create_node_error(connection, node, result)
396
+
397
+ on_delete_node_result(connection, node, result)
398
+
399
+ on_delete_node_error(connection, node, result)
400
+
401
+ on_pubsub_subscribe_result(connection, result, node)
402
+
403
+ on_pubsub_subscribe_error(connection, result, node)
404
+
405
+ on_pubsub_subscribe_error_item_not_found(connection, result, node)
406
+
407
+ on_pubsub_unsubscribe_result(connection, result, node)
408
+
409
+ on_pubsub_unsubscribe_error(connection, result, node)
410
+
411
+ === ERRORS
412
+
413
+ on_unsupported_message(connection, stanza)
414
+
415
+ == Copyright
416
+
417
+ Copyright (c) 2009 Troy Stribling. See LICENSE for details.