troystribling-agent_xmpp 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/README.rdoc +397 -2
  2. data/Rakefile +33 -21
  3. data/VERSION +1 -1
  4. data/agent_xmpp.gemspec +78 -33
  5. data/lib/agent_xmpp.rb +11 -7
  6. data/lib/agent_xmpp/app.rb +0 -5
  7. data/lib/agent_xmpp/app/boot.rb +47 -33
  8. data/lib/agent_xmpp/app/controller.rb +135 -19
  9. data/lib/agent_xmpp/client.rb +6 -1
  10. data/lib/agent_xmpp/client/client.rb +22 -155
  11. data/lib/agent_xmpp/client/connection.rb +41 -250
  12. data/lib/agent_xmpp/client/message_delegate.rb +706 -0
  13. data/lib/agent_xmpp/client/message_pipe.rb +176 -0
  14. data/lib/agent_xmpp/client/publish_model.rb +65 -0
  15. data/lib/agent_xmpp/{app/format.rb → client/response.rb} +19 -24
  16. data/lib/agent_xmpp/client/roster_model.rb +139 -0
  17. data/lib/agent_xmpp/client/services_model.rb +97 -0
  18. data/lib/agent_xmpp/config.rb +45 -0
  19. data/lib/agent_xmpp/main.rb +126 -0
  20. data/lib/agent_xmpp/patches.rb +6 -2
  21. data/lib/agent_xmpp/patches/{standard_library_patches/array.rb → array.rb} +14 -7
  22. data/lib/agent_xmpp/patches/{standard_library_patches/float.rb → float.rb} +0 -0
  23. data/lib/agent_xmpp/patches/{standard_library_patches/hash.rb → hash.rb} +3 -3
  24. data/lib/agent_xmpp/patches/{standard_library_patches/object.rb → object.rb} +3 -3
  25. data/lib/agent_xmpp/patches/rexml.rb +69 -0
  26. data/lib/agent_xmpp/patches/{standard_library_patches/string.rb → string.rb} +5 -0
  27. data/lib/agent_xmpp/xmpp.rb +17 -0
  28. data/lib/agent_xmpp/xmpp/element.rb +159 -0
  29. data/lib/agent_xmpp/xmpp/error_response.rb +179 -0
  30. data/lib/agent_xmpp/xmpp/iq.rb +90 -0
  31. data/lib/agent_xmpp/xmpp/iq_command.rb +47 -0
  32. data/lib/agent_xmpp/xmpp/iq_disco.rb +205 -0
  33. data/lib/agent_xmpp/xmpp/iq_pubsub.rb +268 -0
  34. data/lib/agent_xmpp/xmpp/iq_roster.rb +183 -0
  35. data/lib/agent_xmpp/xmpp/iq_version.rb +89 -0
  36. data/lib/agent_xmpp/xmpp/jid.rb +150 -0
  37. data/lib/agent_xmpp/xmpp/message.rb +82 -0
  38. data/lib/agent_xmpp/xmpp/presence.rb +127 -0
  39. data/lib/agent_xmpp/xmpp/sasl.rb +241 -0
  40. data/lib/agent_xmpp/xmpp/stanza.rb +107 -0
  41. data/lib/agent_xmpp/xmpp/x_data.rb +269 -0
  42. data/test/app/app.rb +134 -0
  43. data/test/cases/test_application_message_processing.rb +65 -0
  44. data/test/cases/test_errors.rb +24 -0
  45. data/test/cases/test_presence_management.rb +139 -0
  46. data/test/cases/test_roster_management.rb +214 -0
  47. data/test/cases/test_service_discovery.rb +168 -0
  48. data/test/cases/test_session_management.rb +120 -0
  49. data/test/cases/test_version_discovery.rb +67 -0
  50. data/test/helpers/matchers.rb +23 -0
  51. data/test/helpers/mocks.rb +82 -0
  52. data/test/helpers/test_case_extensions.rb +45 -0
  53. data/test/helpers/test_client.rb +44 -0
  54. data/test/helpers/test_delegate.rb +61 -0
  55. data/test/helpers/test_helper.rb +91 -0
  56. data/test/messages/application_messages.rb +206 -0
  57. data/test/messages/error_messages.rb +35 -0
  58. data/test/messages/presence_messages.rb +66 -0
  59. data/test/messages/roster_messages.rb +126 -0
  60. data/test/messages/service_discovery_messages.rb +201 -0
  61. data/test/messages/session_messages.rb +158 -0
  62. data/test/messages/version_discovery_messages.rb +69 -0
  63. data/test/peer/peer.rb +36 -0
  64. data/test/xml_messages.txt +197 -0
  65. metadata +82 -42
  66. data/bin/agent_xmpp +0 -56
  67. data/lib/agent_xmpp/app/chat_message_body_controller.rb +0 -16
  68. data/lib/agent_xmpp/app/map.rb +0 -45
  69. data/lib/agent_xmpp/app/routes.rb +0 -77
  70. data/lib/agent_xmpp/app/view.rb +0 -49
  71. data/lib/agent_xmpp/client/parser.rb +0 -71
  72. data/lib/agent_xmpp/patches/standard_library_patches.rb +0 -5
  73. data/lib/agent_xmpp/patches/xmpp4r_patches.rb +0 -3
  74. data/lib/agent_xmpp/patches/xmpp4r_patches/command.rb +0 -26
  75. data/lib/agent_xmpp/patches/xmpp4r_patches/iq.rb +0 -26
  76. data/lib/agent_xmpp/patches/xmpp4r_patches/x_data.rb +0 -116
  77. data/lib/agent_xmpp/utils.rb +0 -2
  78. data/lib/agent_xmpp/utils/logger.rb +0 -24
  79. data/lib/agent_xmpp/utils/roster.rb +0 -23
  80. data/lib/agent_xmpp/version.rb +0 -6
  81. data/test/agent_xmpp_test.rb +0 -7
  82. data/test/test_helper.rb +0 -10
@@ -0,0 +1,179 @@
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 NoNameXmlnsRegistered < ArgumentError
10
+ def initialize(klass)
11
+ super "Class #{klass} has not set name and xmlns"
12
+ end
13
+ end
14
+
15
+ #####-------------------------------------------------------------------------------------------------------
16
+ class ErrorResponse < Element
17
+
18
+ #.........................................................................................................
19
+ name_xmlns 'error'
20
+ xmpp_attribute :type, :sym => true
21
+
22
+ #####-------------------------------------------------------------------------------------------------------
23
+ class << self
24
+
25
+ #.........................................................................................................
26
+ def unsupported_payload(params)
27
+ command_error(params, 'bad-request', 'unsupported payload')
28
+ end
29
+
30
+ #.........................................................................................................
31
+ def no_route(params)
32
+ command_error(params, 'item-not-found', 'no route for specified command node')
33
+ end
34
+
35
+ #.........................................................................................................
36
+ def feature_not_implemented(request)
37
+ iq_error(request, 'feature-not-implemented', 'feature not implemented')
38
+ end
39
+
40
+ #.........................................................................................................
41
+ def service_unavailable(request)
42
+ query_error(request, 'service-unavailable', 'service unavailable')
43
+ end
44
+
45
+ #.........................................................................................................
46
+ def item_not_found(request)
47
+ query_error(request, 'item-not-found', 'item not found')
48
+ end
49
+
50
+ ####........................................................................................................
51
+ private
52
+
53
+ #.........................................................................................................
54
+ def iq_error(request, condition, text)
55
+ iq = Xmpp::Iq.new(:error, request.from)
56
+ iq.id = request.id unless request.id.nil?
57
+ iq.error = Xmpp::ErrorResponse.new(condition, text)
58
+ Send(iq)
59
+ end
60
+
61
+ #.........................................................................................................
62
+ def query_error(request, condition, text)
63
+ iq = Xmpp::Iq.new(:error, request.from)
64
+ iq.id = request.id unless request.id.nil?
65
+ iq.query = Xmpp::IqQuery.new
66
+ iq.query.add_namespace(request.query.namespace)
67
+ iq.query.attributes['node'] = request.query.node if request.query.node
68
+ iq.error = Xmpp::ErrorResponse.new(condition, text)
69
+ Send(iq)
70
+ end
71
+
72
+ #.........................................................................................................
73
+ def command_error(params, condition, text)
74
+ iq = Xmpp::Iq.new(:error, params[:from])
75
+ iq.id = params[:id] unless params[:id].nil?
76
+ iq.command = Xmpp::IqCommand.new(params[:node], params[:action])
77
+ iq.command = Xmpp::ErrorResponse.new(condition, text)
78
+ Send(iq)
79
+ end
80
+
81
+ #### self
82
+ end
83
+
84
+ #.......................................................................................................
85
+ def initialize(errorcondition=nil, text=nil)
86
+ if errorcondition.nil?
87
+ super()
88
+ else
89
+ errortype = nil
90
+ errorcode = nil
91
+ @@Errors.each do |cond,type,code|
92
+ if errorcondition == cond
93
+ errortype = type
94
+ errorcode = code
95
+ end
96
+ end
97
+ raise ArgumentError, "Unknown error condition when initializing ErrorReponse" if errortype.nil? || errorcode.nil?
98
+ super()
99
+ self.error = errorcondition unless errorcondition.nil?
100
+ self.type = errortype unless errortype.nil?
101
+ self.code = errorcode unless errorcode.nil?
102
+ end
103
+ self.text = text unless text.nil?
104
+ end
105
+
106
+ #.......................................................................................................
107
+ def code
108
+ (c = attributes['code']).nil? ? nil : c.to_i
109
+ end
110
+
111
+ #.......................................................................................................
112
+ def code=(i)
113
+ attributes['code'] = i.nil? ? nil : i.to_s
114
+ end
115
+
116
+ #.......................................................................................................
117
+ def error
118
+ name = nil
119
+ each_element {|e| name = e.name if (e.namespace == 'urn:ietf:params:xml:ns:xmpp-stanzas') && (e.name != 'text') }
120
+ name
121
+ end
122
+
123
+ #.......................................................................................................
124
+ def error=(s)
125
+ xe = nil
126
+ each_element {|e| xe = e if (e.namespace == 'urn:ietf:params:xml:ns:xmpp-stanzas') && (e.name != 'text') }
127
+ unless xe.nil?
128
+ delete_element(xe)
129
+ end
130
+ add_element(s).add_namespace('urn:ietf:params:xml:ns:xmpp-stanzas')
131
+ end
132
+
133
+ #.......................................................................................................
134
+ def text
135
+ first_element_text('text') || super
136
+ end
137
+
138
+ #.......................................................................................................
139
+ def text=(s)
140
+ delete_elements('text')
141
+ unless s.nil?
142
+ e = add_element('text')
143
+ e.add_namespace('urn:ietf:params:xml:ns:xmpp-stanzas')
144
+ e.text = s
145
+ end
146
+ end
147
+
148
+ #.......................................................................................................
149
+ @@Errors = [['bad-request', :modify, 400],
150
+ ['conflict', :cancel, 409],
151
+ ['feature-not-implemented', :cancel, 501],
152
+ ['forbidden', :auth, 403],
153
+ ['gone', :modify, 302],
154
+ ['internal-server-error', :wait, 500],
155
+ ['item-not-found', :cancel, 404],
156
+ ['jid-malformed', :modify, 400],
157
+ ['not-acceptable', :modify, 406],
158
+ ['not-allowed', :cancel, 405],
159
+ ['not-authorized', :auth, 401],
160
+ ['payment-required', :auth, 402],
161
+ ['recipient-unavailable', :wait, 404],
162
+ ['redirect', :modify, 302],
163
+ ['registration-required', :auth, 407],
164
+ ['remote-server-not-found', :cancel, 404],
165
+ ['remote-server-timeout', :wait, 504],
166
+ ['resource-constraint', :wait, 500],
167
+ ['service-unavailable', :cancel, 503],
168
+ ['subscription-required', :auth, 407],
169
+ ['undefined-condition', nil, 500],
170
+ ['unexpected-request', :wait, 400]]
171
+
172
+ #### ErrorResponse
173
+ end
174
+
175
+ #### XMPP
176
+ end
177
+
178
+ #### AgentXmpp
179
+ end
@@ -0,0 +1,90 @@
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 Iq < Stanza
10
+
11
+ #.....................................................................................................
12
+ name_xmlns 'iq', 'jabber:client'
13
+ xmpp_child :query, :error, :pubsub, :command, :bind, :session
14
+
15
+ #####-----------------------------------------------------------------------------------------------------
16
+ class << self
17
+
18
+ #.........................................................................................................
19
+ def bind(pipe)
20
+ iq = new_bind(AgentXmpp.jid)
21
+ Send(iq) do |r|
22
+ if r.type == :result and full_jid = r.first_element('//jid') and full_jid.text
23
+ AgentXmpp.jid = Jid.new(full_jid.text)
24
+ pipe.broadcast_to_delegates(:did_bind, pipe)
25
+ elsif r.type.eql?(:error) and r.bind
26
+ raise AgentXmppError, "resource bind failed"
27
+ end
28
+ end
29
+ end
30
+
31
+ #.........................................................................................................
32
+ def session(pipe)
33
+ iq = new_session
34
+ Send(iq) do |r|
35
+ if r.type == :result
36
+ pipe.broadcast_to_delegates(:did_start_session, pipe)
37
+ elsif r.type.eql?(:error) and r.session
38
+ raise AgentXmppError, "session start failed"
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ #.......................................................................................................
46
+ def new_bind(jid)
47
+ iq = Iq.new(:set)
48
+ iq.bind = REXML::Element.new('bind')
49
+ iq.bind.add_namespace('urn:ietf:params:xml:ns:xmpp-bind')
50
+ resource = iq.bind.add(REXML::Element.new('resource'))
51
+ resource.text = jid.resource
52
+ iq
53
+ end
54
+
55
+ #.......................................................................................................
56
+ def new_session
57
+ iq = Iq.new(:set)
58
+ iq.session =REXML::Element.new('session')
59
+ iq.session.add_namespace('urn:ietf:params:xml:ns:xmpp-session')
60
+ iq
61
+ end
62
+
63
+ #### self
64
+ end
65
+
66
+ #.......................................................................................................
67
+ def initialize(type = nil, to = nil)
68
+ super()
69
+ self.to = to unless to.nil?
70
+ self.type = type unless type.nil?
71
+ end
72
+
73
+ #.......................................................................................................
74
+ def queryns
75
+ (e = first_element('query')).nil? ? nil : e.namespace
76
+ end
77
+
78
+ #### Iq
79
+ end
80
+
81
+ #####-------------------------------------------------------------------------------------------------------
82
+ class IqQuery < Element
83
+ name_xmlns 'query'
84
+ end
85
+
86
+ #### XMPP
87
+ end
88
+
89
+ #### AgentXmpp
90
+ end
@@ -0,0 +1,47 @@
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 IqCommand < Element
10
+
11
+ #.....................................................................................................
12
+ name_xmlns 'command', 'http://jabber.org/protocol/commands'
13
+ xmpp_attribute :node, :sessionid
14
+ xmpp_attribute :action, :status, :sym => true
15
+ xmpp_child :actions, :x
16
+
17
+ #####-------------------------------------------------------------------------------------------------------
18
+ class << self
19
+
20
+ #.........................................................................................................
21
+ def result(args)
22
+ iq = Iq.new(:result, args[:to])
23
+ iq.id = args[:id] unless args[:id].nil?
24
+ iq.command = new(args[:node])
25
+ iq.command.status = 'completed'
26
+ iq.command << args[:payload] unless args[:payload].nil?
27
+ Send(iq)
28
+ end
29
+
30
+ #### self
31
+ end
32
+
33
+ #.....................................................................................................
34
+ def initialize(node=nil, action=nil)
35
+ super()
36
+ self.node = node if node
37
+ self.action = action if action
38
+ end
39
+
40
+ #### IqCommand
41
+ end
42
+
43
+ #### XMPP
44
+ end
45
+
46
+ #### AgentXmpp
47
+ end
@@ -0,0 +1,205 @@
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 IqDiscoItems < IqQuery
10
+
11
+ #.........................................................................................................
12
+ name_xmlns 'query', 'http://jabber.org/protocol/disco#items'
13
+ xmpp_attribute :node
14
+
15
+ #####-----------------------------------------------------------------------------------------------------
16
+ class << self
17
+
18
+ #.........................................................................................................
19
+ def get(pipe, to=nil, node=nil)
20
+ iq = Iq.new(:get, to)
21
+ iq.query = new
22
+ iq.query.node = node if node
23
+ Send(iq) do |r|
24
+ if (r.type == :result) && r.query.kind_of?(Xmpp::IqDiscoItems)
25
+ pipe.broadcast_to_delegates(:did_receive_discoitems_result, pipe, r)
26
+ elsif r.type.eql?(:error)
27
+ pipe.broadcast_to_delegates(:did_receive_discoitems_error, pipe, r)
28
+ end
29
+ end
30
+ end
31
+
32
+ #.........................................................................................................
33
+ def result(pipe, request)
34
+ iq = Xmpp::Iq.new(:result, request.from.to_s)
35
+ iq.id = request.id unless request.id.nil?
36
+ iq.query = new
37
+ Send(iq)
38
+ end
39
+
40
+ #.........................................................................................................
41
+ def result_command_nodes(pipe, request)
42
+ iq = Xmpp::Iq.new(:result, request.from.to_s)
43
+ iq.id = request.id unless request.id.nil?
44
+ iq.query = new
45
+ iq.query.node = 'http://jabber.org/protocol/commands'
46
+ iq.query.items = BaseController.command_nodes.map{|n| {:node => n, :name => n.humanize, :jid => AgentXmpp.jid.to_s}}
47
+ Send(iq)
48
+ end
49
+
50
+ #### self
51
+ end
52
+
53
+ #.........................................................................................................
54
+ def items
55
+ elements.to_a('item')
56
+ end
57
+
58
+ #.........................................................................................................
59
+ def items=(its)
60
+ its.each{|i| self << DiscoItem.new(i[:jid], i[:name], i[:node])}
61
+ end
62
+
63
+ #### IqDiscoItems
64
+ end
65
+
66
+ #####-------------------------------------------------------------------------------------------------------
67
+ class IqDiscoInfo < IqQuery
68
+
69
+ #.........................................................................................................
70
+ name_xmlns 'query', 'http://jabber.org/protocol/disco#info'
71
+ xmpp_attribute :node
72
+
73
+ #####-------------------------------------------------------------------------------------------------------
74
+ class << self
75
+
76
+ #.........................................................................................................
77
+ def get(pipe, to=nil, node=nil)
78
+ iq = Iq.new(:get, to)
79
+ iq.query = new
80
+ iq.query.node = node if node
81
+ Send(iq) do |r|
82
+ if (r.type == :result) && r.query.kind_of?(Xmpp::IqDiscoInfo)
83
+ pipe.broadcast_to_delegates(:did_receive_discoinfo_result, pipe, r)
84
+ elsif r.type.eql?(:error)
85
+ pipe.broadcast_to_delegates(:did_receive_discoinfo_error, pipe, r)
86
+ end
87
+ end
88
+ end
89
+
90
+ #.........................................................................................................
91
+ def result(pipe, request)
92
+ iq = Xmpp::Iq.new(:result, request.from.to_s)
93
+ iq.id = request.id unless request.id.nil?
94
+ iq.query = IqDiscoInfo.new
95
+ iq.query << DiscoIdentity.new(AgentXmpp::IDENTITY[:category], AgentXmpp::IDENTITY[:name], AgentXmpp::IDENTITY[:type])
96
+ iq.query.features = AgentXmpp::FEATURES
97
+ Send(iq)
98
+ end
99
+
100
+ #### self
101
+ end
102
+
103
+ #.........................................................................................................
104
+ def identities
105
+ elements.to_a('identity')
106
+ end
107
+
108
+ #.........................................................................................................
109
+ def features
110
+ elements.to_a('feature')
111
+ end
112
+
113
+ #.........................................................................................................
114
+ def features=(feats)
115
+ feats.each{|f| self << DiscoFeature.new(f)}
116
+ end
117
+
118
+ #### IqDiscoInfo
119
+ end
120
+
121
+ #####-------------------------------------------------------------------------------------------------------
122
+ class DiscoItem < Element
123
+
124
+ #.........................................................................................................
125
+ name_xmlns 'item', 'http://jabber.org/protocol/disco#items'
126
+ xmpp_attribute :node
127
+
128
+ #.........................................................................................................
129
+ def initialize(jid=nil, iname=nil, node=nil)
130
+ super()
131
+ self.jid = jid if jid
132
+ self.iname = iname if iname
133
+ self.node = node if node
134
+ end
135
+
136
+ #.........................................................................................................
137
+ def jid
138
+ Jid.new(attributes['jid'])
139
+ end
140
+
141
+ #.........................................................................................................
142
+ def jid=(val)
143
+ attributes['jid'] = val.to_s
144
+ end
145
+
146
+ def iname
147
+ attributes['name']
148
+ end
149
+
150
+ #.........................................................................................................
151
+ def iname=(val)
152
+ attributes['name'] = val
153
+ end
154
+
155
+ #### DiscoItem
156
+ end
157
+
158
+ #####-------------------------------------------------------------------------------------------------------
159
+ class DiscoIdentity < Element
160
+
161
+ #.........................................................................................................
162
+ name_xmlns 'identity', 'http://jabber.org/protocol/disco#info'
163
+ xmpp_attribute :node, :category, :type
164
+
165
+ #.........................................................................................................
166
+ def initialize(category=nil, iname=nil, type=nil)
167
+ super()
168
+ self.category = category if category
169
+ self.iname = iname if iname
170
+ self.type = type if type
171
+ end
172
+
173
+ def iname
174
+ attributes['name']
175
+ end
176
+
177
+ #.........................................................................................................
178
+ def iname=(val)
179
+ attributes['name'] = val
180
+ end
181
+
182
+ #### DiscoIdentity
183
+ end
184
+
185
+ #####-------------------------------------------------------------------------------------------------------
186
+ class DiscoFeature < Element
187
+
188
+ #.........................................................................................................
189
+ name_xmlns 'feature', 'http://jabber.org/protocol/disco#info'
190
+ xmpp_attribute :var
191
+
192
+ #.........................................................................................................
193
+ def initialize(var=nil)
194
+ super()
195
+ self.var = var
196
+ end
197
+
198
+ #### DiscoFeature
199
+ end
200
+
201
+ #### Xmpp
202
+ end
203
+
204
+ #### AgentXmpp
205
+ end