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,61 @@
1
+ ##############################################################################################################
2
+ module AgentXmpp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Subscription
6
+
7
+ #####-------------------------------------------------------------------------------------------------------
8
+ class << self
9
+
10
+ #.........................................................................................................
11
+ def subscriptions(renew=false)
12
+ @subscriptions ||= AgentXmpp.in_memory_db[:subscriptions]
13
+ end
14
+
15
+ #.........................................................................................................
16
+ def find_all
17
+ subscriptions.all
18
+ end
19
+
20
+ #.........................................................................................................
21
+ def update(msg, node, serv)
22
+ case msg
23
+ when AgentXmpp::Xmpp::Subscription then update_with_subscription(msg, node, serv)
24
+ when AgentXmpp::Xmpp::Iq then update_with_subscription(msg.pubsub.subscription, node, serv)
25
+ end
26
+ end
27
+
28
+ #.........................................................................................................
29
+ def destroy_by_node(node)
30
+ subscriptions.filter(:node => node).delete
31
+ end
32
+
33
+ #.........................................................................................................
34
+ def stats_by_node
35
+ find_all.map do |s|
36
+ node = s[:node].split('/')
37
+ Message.stats_by_node(s[:node]).update(:node=>node.last, :jid=>"#{node[3]}@#{node[2]}")
38
+ end
39
+ end
40
+
41
+ #.........................................................................................................
42
+ # private
43
+ #.........................................................................................................
44
+ def update_with_subscription(msg, node, serv)
45
+ begin
46
+ subscriptions << {:node => node, :subscription => msg.subscription, :service => serv}
47
+ rescue
48
+ end
49
+ end
50
+
51
+ #.........................................................................................................
52
+ private :update_with_subscription
53
+
54
+ #### self
55
+ end
56
+
57
+ #### Subscription
58
+ end
59
+
60
+ #### AgentXmpp
61
+ end
@@ -0,0 +1,107 @@
1
+ ##############################################################################################################
2
+ module AgentXmpp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class << self
6
+
7
+ #####-----------------------------------------------------------------------------------------------------
8
+ def create_in_memory_db
9
+ in_memory_db.create_table :roster do
10
+ primary_key :id
11
+ column :contact_id, :integer
12
+ column :jid, :text, :unique=>true
13
+ column :status, :text
14
+ column :client_name, :text
15
+ column :client_version, :text
16
+ column :client_os, :text
17
+ end
18
+ in_memory_db.create_table :services do
19
+ primary_key :id
20
+ column :jid, :text
21
+ column :name, :text
22
+ column :category, :text
23
+ column :type, :text
24
+ column :node, :text
25
+ unique [:node, :jid]
26
+ end
27
+ in_memory_db.create_table :service_items do
28
+ primary_key :id
29
+ column :parent_node, :text
30
+ column :service, :text
31
+ column :node, :text
32
+ column :jid, :text
33
+ column :name, :text
34
+ unique [:node, :service]
35
+ end
36
+ in_memory_db.create_table :service_features do
37
+ primary_key :id
38
+ column :node, :text
39
+ column :service, :text
40
+ column :var, :text
41
+ unique [:node, :service, :var]
42
+ end
43
+ in_memory_db.create_table :publications do
44
+ primary_key :id
45
+ column :node, :text, :unique=>true
46
+ column :status, :text
47
+ column :title, :text
48
+ column :access_model, :text
49
+ column :max_items, :integer
50
+ column :deliver_notifications, :integer
51
+ column :deliver_payloads, :integer
52
+ column :persist_items, :integer
53
+ column :subscribe, :integer
54
+ column :notify_config, :integer
55
+ column :notify_delete, :integer
56
+ column :notify_retract, :integer
57
+ end
58
+ in_memory_db.create_table :subscriptions do
59
+ primary_key :id
60
+ column :node, :text, :unique=>true
61
+ column :service, :text
62
+ column :subscription, :text
63
+ end
64
+ end
65
+
66
+ #####-----------------------------------------------------------------------------------------------------
67
+ def create_agent_xmpp_db
68
+ unless agent_xmpp_db.table_exists? :version
69
+ agent_xmpp_db.create_table :version do
70
+ primary_key :id
71
+ integer :number
72
+ end
73
+ end
74
+ version << {:number=>1} if version.count.eql?(0)
75
+ unless agent_xmpp_db.table_exists? :contacts
76
+ agent_xmpp_db.create_table :contacts do
77
+ primary_key :id
78
+ column :jid, :text, :unique=>true
79
+ column :ask, :text
80
+ column :subscription, :text
81
+ column :groups, :text
82
+ end
83
+ end
84
+ unless agent_xmpp_db.table_exists? :messages
85
+ agent_xmpp_db.create_table :messages do
86
+ primary_key :id
87
+ column :message_text, :text
88
+ column :content_type, :text
89
+ column :message_type, :text
90
+ column :to_jid, :text
91
+ column :from_jid, :text
92
+ column :node, :text
93
+ column :item_id, :text
94
+ Time :created_at
95
+ end
96
+ end
97
+ end
98
+
99
+ #####-----------------------------------------------------------------------------------------------------
100
+ def upgrade_agent_xmpp_db
101
+ end
102
+
103
+ #### self
104
+ end
105
+
106
+ #### AgentXmpp
107
+ end
@@ -0,0 +1,7 @@
1
+ require 'agent_xmpp/patches/object'
2
+ require 'agent_xmpp/patches/array'
3
+ require 'agent_xmpp/patches/hash'
4
+ require 'agent_xmpp/patches/string'
5
+ require 'agent_xmpp/patches/float'
6
+ require 'agent_xmpp/patches/rexml'
7
+
@@ -0,0 +1,32 @@
1
+ ##############################################################################################################
2
+ class Array
3
+
4
+ #......................................................................................................
5
+ def to_x_data(type = 'result')
6
+ data = AgentXmpp::Xmpp::XData.new(type)
7
+ if first.kind_of?(Hash)
8
+ field_type = lambda{|v| v.kind_of?(Array) ? 'list-multi' : nil}
9
+ reported = AgentXmpp::Xmpp::XDataReported.new
10
+ first.each_key {|var| reported.add_field(var.to_s)}
11
+ data << reported
12
+ each do |fields|
13
+ item = AgentXmpp::Xmpp::XDataItem.new
14
+ fields.each{|var, val| item.add_field_with_value(var.to_s, [val].flatten.collect{|v| v.to_s}, field_type[val])}
15
+ data << item
16
+ end
17
+ else
18
+ field = AgentXmpp::Xmpp::XDataField.new
19
+ field.values = map{|v| v.to_s}
20
+ field.type ='list-multi'
21
+ data << field
22
+ end
23
+ data
24
+ end
25
+
26
+ #......................................................................................................
27
+ def smash
28
+ self.flatten.compact
29
+ end
30
+
31
+ #### Array
32
+ end
@@ -0,0 +1,10 @@
1
+ ##############################################################################################################
2
+ class Float
3
+
4
+ #......................................................................................................
5
+ def precision(p = 3)
6
+ (10.0**p*self).round.to_f/10.0**p
7
+ end
8
+
9
+ #### Float
10
+ end
@@ -0,0 +1,13 @@
1
+ ##############################################################################################################
2
+ class Hash
3
+
4
+ #.......................................................................................................
5
+ def to_x_data(type = 'result')
6
+ field_type = lambda{|v| v.kind_of?(Array) ? 'list-multi' : nil}
7
+ inject(AgentXmpp::Xmpp::XData.new(type)) do |data, (var, val)|
8
+ data.add_field_with_value(var, [val].flatten.map{|v| v.to_s}, field_type[val])
9
+ end
10
+ end
11
+
12
+ #### Hash
13
+ end
@@ -0,0 +1,15 @@
1
+ ##############################################################################################################
2
+ class Object
3
+
4
+ #.......................................................................................................
5
+ def to_x_data(type='result')
6
+ AgentXmpp::Xmpp::XData.new(type).add_field_with_value(nil, to_s)
7
+ end
8
+
9
+ #.......................................................................................................
10
+ def define_meta_class_method(name, &blk)
11
+ (class << self; self; end).instance_eval {define_method(name, &blk)}
12
+ end
13
+
14
+ #### Object
15
+ end
@@ -0,0 +1,69 @@
1
+ # Original from XMPP4R - XMPP Library for Ruby Website::http://home.gna.org/xmpp4r/
2
+ ##############################################################################################################
3
+ module REXML
4
+
5
+ ####----------------------------------------------------------------------------------------------------
6
+ class Element
7
+
8
+ #.......................................................................................................
9
+ def replace_element_text(e, t)
10
+ el = first_element(e)
11
+ if el.nil?
12
+ el = REXML::Element.new(e)
13
+ add_element(el)
14
+ end
15
+ el.text = t if t
16
+ self
17
+ end
18
+
19
+ #.......................................................................................................
20
+ def first_element(e)
21
+ elements.to_a(e).first
22
+ end
23
+
24
+ #.......................................................................................................
25
+ def first_element_text(e)
26
+ el = first_element(e)
27
+ el.nil? ? nil : el.text
28
+ end
29
+
30
+ #.......................................................................................................
31
+ def typed_add(e)
32
+ add(e)
33
+ end
34
+
35
+ #.......................................................................................................
36
+ def import(xmlelement)
37
+ if @name and @name != xmlelement.name
38
+ raise "Trying to import an #{xmlelement.name} to a #{@name} !"
39
+ end
40
+ add_attributes(xmlelement.attributes.clone)
41
+ @context = xmlelement.context
42
+ xmlelement.each do |e|
43
+ if e.kind_of? REXML::Element
44
+ typed_add(e.deep_clone)
45
+ elsif e.kind_of? REXML::Text
46
+ add_text(e.value)
47
+ else
48
+ add(e.clone)
49
+ end
50
+ end
51
+ self
52
+ end
53
+
54
+ #.......................................................................................................
55
+ def self.import(xmlelement)
56
+ self.new(xmlelement.name).import(xmlelement)
57
+ end
58
+
59
+ #.......................................................................................................
60
+ def delete_elements(element)
61
+ elements.delete_all(element)
62
+ end
63
+
64
+ #### Element
65
+ end
66
+
67
+ #### REXML
68
+ end
69
+
@@ -0,0 +1,15 @@
1
+ ##############################################################################################################
2
+ class String
3
+
4
+ #......................................................................................................
5
+ def classify
6
+ split('_').collect{|s| s.capitalize}.join
7
+ end
8
+
9
+ #......................................................................................................
10
+ def humanize
11
+ gsub(/_/, ' ')
12
+ end
13
+
14
+ #### String
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'agent_xmpp/xmpp/element'
2
+ require 'agent_xmpp/xmpp/x_data'
3
+ require 'agent_xmpp/xmpp/error_response'
4
+ require 'agent_xmpp/xmpp/entry'
5
+
6
+ require 'agent_xmpp/xmpp/stanza'
7
+ require 'agent_xmpp/xmpp/message'
8
+ require 'agent_xmpp/xmpp/presence'
9
+ require 'agent_xmpp/xmpp/iq'
10
+
11
+ require 'agent_xmpp/xmpp/jid'
12
+ require 'agent_xmpp/xmpp/sasl'
13
+
14
+ require 'agent_xmpp/xmpp/iq_command'
15
+ require 'agent_xmpp/xmpp/iq_version'
16
+ require 'agent_xmpp/xmpp/iq_roster'
17
+ require 'agent_xmpp/xmpp/iq_disco'
18
+ require 'agent_xmpp/xmpp/iq_pubsub'
@@ -0,0 +1,158 @@
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 Element < REXML::Element
10
+
11
+ #.......................................................................................................
12
+ @@name_xmlns_classes = {}
13
+
14
+ #####-------------------------------------------------------------------------------------------------------
15
+ class << self
16
+
17
+ #.......................................................................................................
18
+ def name_xmlns(name, xmlns=nil)
19
+ @@name_xmlns_classes[[name, xmlns]] = self
20
+ end
21
+
22
+ #.......................................................................................................
23
+ def name_xmlns_for_class(klass)
24
+ klass.ancestors.each do |klass1|
25
+ @@name_xmlns_classes.each do |name_xmlns,k|
26
+ if klass1 == k
27
+ return name_xmlns
28
+ end
29
+ end
30
+ end
31
+ raise NoNameXmlnsRegistered.new(klass)
32
+ end
33
+
34
+ #.......................................................................................................
35
+ def class_for_name_xmlns(name, xmlns)
36
+ if @@name_xmlns_classes.has_key? [name, xmlns]
37
+ @@name_xmlns_classes[[name, xmlns]]
38
+ elsif @@name_xmlns_classes.has_key? [name, nil]
39
+ @@name_xmlns_classes[[name, nil]]
40
+ else
41
+ REXML::Element
42
+ end
43
+ end
44
+
45
+ #.......................................................................................................
46
+ def import(element)
47
+ klass = class_for_name_xmlns(element.name, element.namespace)
48
+ if klass != self and klass.ancestors.include?(self)
49
+ klass.new.import(element)
50
+ else
51
+ self.new.import(element)
52
+ end
53
+ end
54
+
55
+ #.....................................................................................................
56
+ def xmpp_attribute(*args)
57
+ sym = (args.pop[:sym] if args.last.kind_of?(Hash)).nil? ? '' : '.to_sym'
58
+ args.each do |a|
59
+ class_eval <<-DEF
60
+ def #{a.to_s}
61
+ attr = attributes['#{a.to_s}']
62
+ attr.nil? ? nil : attr#{sym}
63
+ end
64
+ def #{a.to_s}=(v)
65
+ attributes['#{a.to_s}'] = v.to_s
66
+ end
67
+ DEF
68
+ end
69
+ end
70
+
71
+ #.......................................................................................................
72
+ def xmpp_child(*args)
73
+ args.each do |a|
74
+ class_eval <<-DEF
75
+ def #{a.to_s}
76
+ first_element('#{a.to_s}')
77
+ end
78
+ def #{a.to_s}=(v)
79
+ delete_elements(v.name)
80
+ add(v)
81
+ end
82
+ DEF
83
+ end
84
+ end
85
+
86
+ #### self
87
+ end
88
+
89
+ #.......................................................................................................
90
+ def initialize(*arg)
91
+ if arg.empty?
92
+ name, xmlns = self.class::name_xmlns_for_class(self.class)
93
+ super(name)
94
+ add_namespace(xmlns)
95
+ else
96
+ super
97
+ end
98
+ end
99
+
100
+ #.......................................................................................................
101
+ def typed_add(element)
102
+ if element.kind_of? REXML::Element
103
+ element_ns = (element.namespace.to_s == '') ? namespace : element.namespace
104
+ klass = Element::class_for_name_xmlns(element.name, element_ns)
105
+ if klass != element.class
106
+ element = klass.import(element)
107
+ end
108
+ end
109
+ super(element)
110
+ end
111
+
112
+ #.......................................................................................................
113
+ def parent=(new_parent)
114
+ if parent and parent.namespace('') == namespace('') and attributes['xmlns'].nil?
115
+ add_namespace parent.namespace('')
116
+ end
117
+ super
118
+ if new_parent and new_parent.namespace('') == namespace('')
119
+ delete_namespace
120
+ end
121
+ end
122
+
123
+ #.......................................................................................................
124
+ def clone
125
+ cloned = self.class.new
126
+ cloned.add_attributes self.attributes.clone
127
+ cloned.context = @context
128
+ cloned
129
+ end
130
+
131
+ #.......................................................................................................
132
+ def xml_lang
133
+ attributes['xml:lang']
134
+ end
135
+
136
+ #.......................................................................................................
137
+ def xml_lang=(l)
138
+ attributes['xml:lang'] = l
139
+ end
140
+
141
+ #.......................................................................................................
142
+ def set_xml_lang(l)
143
+ self.xml_lang = l; self
144
+ end
145
+
146
+ #.....................................................................................................
147
+ def <<(child)
148
+ add(child); self
149
+ end
150
+
151
+ #### Element
152
+ end
153
+
154
+ #### XMPP
155
+ end
156
+
157
+ #### AgentXmpp
158
+ end