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,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