omf_common 6.0.0.pre.8 → 6.0.0.pre.10
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/omf_common.rb +12 -20
- data/lib/omf_common/comm.rb +53 -0
- data/lib/omf_common/default_logging.rb +41 -0
- data/lib/omf_common/dsl/xmpp.rb +70 -61
- data/lib/omf_common/key.rb +14 -0
- data/lib/omf_common/message.rb +54 -24
- data/lib/omf_common/protocol/6.0.rnc +29 -42
- data/lib/omf_common/protocol/6.0.rng +145 -107
- data/lib/omf_common/relaxng_schema.rb +17 -0
- data/lib/omf_common/topic.rb +1 -1
- data/lib/omf_common/version.rb +1 -1
- data/omf_common.gemspec +1 -1
- data/test/fixture/pubsub.rb +4 -4
- data/test/omf_common/dsl/xmpp_spec.rb +9 -9
- data/test/omf_common/message_spec.rb +22 -3
- data/test/omf_common/topic_message_spec.rb +5 -5
- data/test/omf_common/topic_spec.rb +1 -1
- metadata +17 -5
data/lib/omf_common.rb
CHANGED
@@ -1,25 +1,17 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
require "omf_common/version"
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
require 'omf_common/default_logging'
|
3
|
+
require 'omf_common/version'
|
5
4
|
require 'omf_common/measure'
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
|
14
|
-
# Use global default logger from logging gem
|
15
|
-
include Logging.globally
|
5
|
+
require 'omf_common/message'
|
6
|
+
require 'omf_common/comm'
|
7
|
+
require 'omf_common/command'
|
8
|
+
require 'omf_common/topic'
|
9
|
+
require 'omf_common/topic_message'
|
10
|
+
require 'omf_common/key'
|
11
|
+
require 'omf_common/core_ext/string'
|
12
|
+
require 'omf_common/core_ext/object'
|
16
13
|
|
17
|
-
|
18
|
-
:layout => Logging.layouts.pattern(:date_pattern => '%F %T %z',
|
19
|
-
:pattern => '[%d] %-5l %m\n',
|
20
|
-
:color_scheme => 'default'))
|
21
|
-
Logging.logger.root.appenders = 'stdout'
|
22
|
-
Logging.logger.root.level = :info
|
14
|
+
include OmfCommon::DefaultLogging
|
23
15
|
|
24
16
|
module OmfCommon
|
25
17
|
end
|
data/lib/omf_common/comm.rb
CHANGED
@@ -5,8 +5,61 @@ require 'omf_common/dsl/xmpp_mp'
|
|
5
5
|
module OmfCommon
|
6
6
|
# PubSub communication class, can be extended with different implementations
|
7
7
|
class Comm
|
8
|
+
attr_accessor :published_messages
|
9
|
+
|
8
10
|
def initialize(pubsub_implementation)
|
11
|
+
@published_messages = []
|
9
12
|
self.extend("OmfCommon::DSL::#{pubsub_implementation.to_s.camelize}".constantize)
|
10
13
|
end
|
14
|
+
|
15
|
+
# Generate OMF related message
|
16
|
+
%w(create configure request inform release).each do |m_name|
|
17
|
+
define_method("#{m_name}_message") do |*args, &block|
|
18
|
+
message =
|
19
|
+
if block
|
20
|
+
Message.send(m_name, *args, &block)
|
21
|
+
elsif args[0].kind_of? Array
|
22
|
+
Message.send(m_name) do |v|
|
23
|
+
args[0].each do |opt|
|
24
|
+
if opt.kind_of? Hash
|
25
|
+
opt.each_pair do |key, value|
|
26
|
+
v.property(key, value)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
v.property(opt)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
Message.send(m_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
OmfCommon::TopicMessage.new(message, self)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
%w(created status released failed).each do |inform_type|
|
42
|
+
define_method("on_#{inform_type}_message") do |*args, &message_block|
|
43
|
+
msg_id = args[0].msg_id if args[0]
|
44
|
+
event_block = proc do |event|
|
45
|
+
message_block.call(Message.parse(event.items.first.payload))
|
46
|
+
end
|
47
|
+
guard_block = proc do |event|
|
48
|
+
(event.items?) && (!event.delayed?) &&
|
49
|
+
event.items.first.payload &&
|
50
|
+
(omf_message = Message.parse(event.items.first.payload)) &&
|
51
|
+
omf_message.operation == :inform &&
|
52
|
+
omf_message.read_content(:inform_type) == inform_type.upcase &&
|
53
|
+
(msg_id ? (omf_message.context_id == msg_id) : true)
|
54
|
+
end
|
55
|
+
topic_event(guard_block, &callback_logging(__method__, &event_block))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return a topic object represents pubsub topic
|
60
|
+
#
|
61
|
+
def get_topic(topic_id)
|
62
|
+
OmfCommon::Topic.new(topic_id, self)
|
63
|
+
end
|
11
64
|
end
|
12
65
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'logging'
|
2
|
+
|
3
|
+
module OmfCommon
|
4
|
+
module DefaultLogging
|
5
|
+
# Use global default logger from logging gem
|
6
|
+
include Logging.globally
|
7
|
+
|
8
|
+
Logging.appenders.stdout(
|
9
|
+
'default_stdout',
|
10
|
+
:layout => Logging.layouts.pattern(:date_pattern => '%F %T %z',
|
11
|
+
:pattern => '[%d] %-5l %c: %m\n',
|
12
|
+
:color_scheme => 'default'))
|
13
|
+
Logging.logger.root.appenders = 'default_stdout'
|
14
|
+
Logging.logger.root.level = :info
|
15
|
+
|
16
|
+
# Alias logging method using default logger
|
17
|
+
def info(*args, &block)
|
18
|
+
logger.info(*args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @see #info
|
22
|
+
def debug(*args, &block)
|
23
|
+
logger.debug(*args, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @see #info
|
27
|
+
def error(*args, &block)
|
28
|
+
logger.error(*args, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @see #info
|
32
|
+
def fatal(*args, &block)
|
33
|
+
logger.fatal(*args, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @see #info
|
37
|
+
def warn(*args, &block)
|
38
|
+
logger.warn(*args, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/omf_common/dsl/xmpp.rb
CHANGED
@@ -27,8 +27,31 @@ module OmfCommon
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# Shut down XMPP connection
|
30
|
-
def disconnect
|
31
|
-
|
30
|
+
def disconnect(opts = {})
|
31
|
+
if opts[:delete_affiliations]
|
32
|
+
affiliations do |a|
|
33
|
+
# owner means topics created, owned
|
34
|
+
owner_topics = a[:owner] ? a[:owner].size : 0
|
35
|
+
# none means... topics subscribed to
|
36
|
+
none_topics = a[:none] ? a[:none].size : 0
|
37
|
+
|
38
|
+
if none_topics > 0
|
39
|
+
info "Unsubscribing #{none_topics} pubsub topic(s)"
|
40
|
+
unsubscribe
|
41
|
+
end
|
42
|
+
|
43
|
+
if owner_topics > 0
|
44
|
+
info "Deleting #{owner_topics} pubsub topic(s) in 2 seconds"
|
45
|
+
EM.add_timer(2) do
|
46
|
+
a[:owner].each { |topic| delete_topic(topic) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
shutdown if none_topics == 0 && owner_topics == 0
|
51
|
+
end
|
52
|
+
else
|
53
|
+
shutdown
|
54
|
+
end
|
32
55
|
OmfCommon::DSL::Xmpp::MPConnection.inject(Time.now.to_f, jid, 'disconnect') if OmfCommon::Measure.enabled?
|
33
56
|
end
|
34
57
|
|
@@ -49,8 +72,22 @@ module OmfCommon
|
|
49
72
|
# Subscribe to a pubsub topic
|
50
73
|
#
|
51
74
|
# @param [String] topic Pubsub topic name
|
52
|
-
|
53
|
-
|
75
|
+
# @param [Hash] opts
|
76
|
+
# @option opts [Boolean] :create_if_non_existent create the topic if non-existent, use this option with caution
|
77
|
+
def subscribe(topic, opts = {}, &block)
|
78
|
+
if opts[:create_if_non_existent]
|
79
|
+
affiliations do |a|
|
80
|
+
if a[:owner] && a[:owner].include?(topic)
|
81
|
+
pubsub.subscribe(topic, nil, default_host, &callback_logging(__method__, topic, &block))
|
82
|
+
else
|
83
|
+
create_topic(topic) do
|
84
|
+
pubsub.subscribe(topic, nil, default_host, &callback_logging(__method__, topic, &block))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
else
|
89
|
+
pubsub.subscribe(topic, nil, default_host, &callback_logging(__method__, topic, &block))
|
90
|
+
end
|
54
91
|
MPSubscription.inject(Time.now.to_f, jid, 'join', topic) if OmfCommon::Measure.enabled?
|
55
92
|
end
|
56
93
|
|
@@ -74,34 +111,14 @@ module OmfCommon
|
|
74
111
|
# @param [String] message Any XML fragment to be sent as payload
|
75
112
|
def publish(topic, message, &block)
|
76
113
|
raise StandardError, "Invalid message" unless message.valid?
|
77
|
-
pubsub.publish(topic, message, default_host, &callback_logging(__method__, topic, message.operation, &block))
|
78
|
-
MPPublished.inject(Time.now.to_f, jid, topic, message.to_s.gsub("\n",'')) if OmfCommon::Measure.enabled?
|
79
|
-
end
|
80
|
-
|
81
|
-
# Generate OMF related message
|
82
|
-
%w(create configure request inform release).each do |m_name|
|
83
|
-
define_method("#{m_name}_message") do |*args, &block|
|
84
|
-
message =
|
85
|
-
if block
|
86
|
-
Message.send(m_name, *args, &block)
|
87
|
-
elsif args[0].kind_of? Array
|
88
|
-
Message.send(m_name) do |v|
|
89
|
-
args[0].each do |opt|
|
90
|
-
if opt.kind_of? Hash
|
91
|
-
opt.each_pair do |key, value|
|
92
|
-
v.property(key, value)
|
93
|
-
end
|
94
|
-
else
|
95
|
-
v.property(opt)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
else
|
100
|
-
Message.send(m_name)
|
101
|
-
end
|
102
114
|
|
103
|
-
|
115
|
+
new_block = proc do |stanza|
|
116
|
+
published_messages << OpenSSL::Digest::SHA1.new(message.to_s)
|
117
|
+
block.call(stanza) if block
|
104
118
|
end
|
119
|
+
|
120
|
+
pubsub.publish(topic, message, default_host, &callback_logging(__method__, topic, &new_block))
|
121
|
+
MPPublished.inject(Time.now.to_f, jid, topic, message.to_s.gsub("\n",'')) if OmfCommon::Measure.enabled?
|
105
122
|
end
|
106
123
|
|
107
124
|
# Event machine related method delegation
|
@@ -111,50 +128,42 @@ module OmfCommon
|
|
111
128
|
end
|
112
129
|
end
|
113
130
|
|
114
|
-
%w(created status released failed).each do |inform_type|
|
115
|
-
define_method("on_#{inform_type}_message") do |*args, &message_block|
|
116
|
-
context_id = args[0].context_id if args[0]
|
117
|
-
event_block = proc do |event|
|
118
|
-
message_block.call(Message.parse(event.items.first.payload))
|
119
|
-
end
|
120
|
-
guard_block = proc do |event|
|
121
|
-
(event.items?) && (!event.delayed?) &&
|
122
|
-
event.items.first.payload &&
|
123
|
-
(omf_message = Message.parse(event.items.first.payload)) &&
|
124
|
-
omf_message.operation == :inform &&
|
125
|
-
omf_message.read_content(:inform_type) == inform_type.upcase &&
|
126
|
-
(context_id ? (omf_message.context_id == context_id) : true)
|
127
|
-
end
|
128
|
-
pubsub_event(guard_block, &callback_logging(__method__, &event_block))
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
131
|
# Event callback for pubsub topic event(item published)
|
133
132
|
#
|
134
|
-
def topic_event(&block)
|
133
|
+
def topic_event(additional_guard = nil, &block)
|
135
134
|
guard_block = proc do |event|
|
136
|
-
passed = (event.items?) && (!event.delayed?) && event.items.first.payload
|
135
|
+
passed = (event.items?) && (!event.delayed?) && event.items.first.payload &&
|
136
|
+
!published_messages.include?(OpenSSL::Digest::SHA1.new(event.items.first.payload))
|
137
|
+
|
137
138
|
MPReceived.inject(Time.now.to_f, jid, event.node, event.items.first.payload.to_s.gsub("\n",'')) if OmfCommon::Measure.enabled? && passed
|
138
|
-
|
139
|
+
|
140
|
+
if additional_guard
|
141
|
+
passed && additional_guard.call(event)
|
142
|
+
else
|
143
|
+
passed
|
144
|
+
end
|
139
145
|
end
|
140
146
|
pubsub_event(guard_block, &callback_logging(__method__, &block))
|
141
147
|
end
|
142
148
|
|
143
|
-
# Return a topic object represents pubsub topic
|
144
|
-
#
|
145
|
-
def get_topic(topic_id)
|
146
|
-
OmfCommon::Topic.new(topic_id, self)
|
147
|
-
end
|
148
|
-
|
149
149
|
private
|
150
150
|
|
151
151
|
# Provide a new block wrap to automatically log errors
|
152
152
|
def callback_logging(*args, &block)
|
153
153
|
m = args.empty? ? "OPERATION" : args.map {|v| v.to_s.upcase }.join(" ")
|
154
|
-
proc do |
|
155
|
-
|
156
|
-
|
157
|
-
|
154
|
+
proc do |stanza|
|
155
|
+
if stanza.respond_to?(:error?) && stanza.error?
|
156
|
+
e_stanza = Blather::StanzaError.import(stanza)
|
157
|
+
if [:unexpected_request].include? e_stanza.name
|
158
|
+
logger.debug e_stanza
|
159
|
+
elsif e_stanza.name == :conflict
|
160
|
+
logger.debug e_stanza
|
161
|
+
else
|
162
|
+
logger.warn "#{e_stanza} Original: #{e_stanza.original}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
logger.debug "#{m} SUCCEED" if stanza.respond_to?(:result?) && stanza.result?
|
166
|
+
block.call(stanza) if block
|
158
167
|
end
|
159
168
|
end
|
160
169
|
|
data/lib/omf_common/message.rb
CHANGED
@@ -2,6 +2,8 @@ require 'niceogiri'
|
|
2
2
|
require 'hashie'
|
3
3
|
require 'securerandom'
|
4
4
|
require 'openssl'
|
5
|
+
require 'cgi'
|
6
|
+
require 'omf_common/relaxng_schema'
|
5
7
|
|
6
8
|
module OmfCommon
|
7
9
|
|
@@ -24,10 +26,9 @@ module OmfCommon
|
|
24
26
|
# end
|
25
27
|
#
|
26
28
|
class Message < Niceogiri::XML::Node
|
27
|
-
OMF_NAMESPACE = "http://schema.mytestbed.net/#{OmfCommon::PROTOCOL_VERSION}/protocol"
|
28
|
-
SCHEMA_FILE = "#{File.dirname(__FILE__)}/protocol/#{OmfCommon::PROTOCOL_VERSION}.rng"
|
29
|
+
OMF_NAMESPACE = "http://schema.mytestbed.net/omf/#{OmfCommon::PROTOCOL_VERSION}/protocol"
|
29
30
|
OPERATION = %w(create configure request release inform)
|
30
|
-
# When OML instrumentation is enabled, we do not want to send a the same
|
31
|
+
# When OML instrumentation is enabled, we do not want to send a the same
|
31
32
|
# measurement twice, once when a message is created for publishing to T,
|
32
33
|
# and once when this message comes back (as we are also a subscriber of T)
|
33
34
|
# Thus we keep track of message IDs here (again only when OML is enabled)
|
@@ -38,12 +39,11 @@ module OmfCommon
|
|
38
39
|
define_method(operation) do |*args, &block|
|
39
40
|
xml = new(operation, nil, OMF_NAMESPACE)
|
40
41
|
if operation == 'inform'
|
41
|
-
xml.element('context_id', args[1]
|
42
|
+
xml.element('context_id', args[1]) if args[1]
|
42
43
|
xml.element('inform_type', args[0])
|
43
44
|
else
|
44
|
-
xml.element('
|
45
|
+
xml.element('publish_to', args[0]) if args[0]
|
45
46
|
end
|
46
|
-
xml.element('publish_to', args[0]) if operation == 'request'
|
47
47
|
block.call(xml) if block
|
48
48
|
xml.sign
|
49
49
|
end
|
@@ -54,9 +54,9 @@ module OmfCommon
|
|
54
54
|
xml_root = Nokogiri::XML(xml).root
|
55
55
|
result = new(xml_root.element_name, nil, xml_root.namespace.href).inherit(xml_root)
|
56
56
|
if OmfCommon::Measure.enabled? && !@@msg_id_list.include?(result.msg_id)
|
57
|
-
MPMessage.inject(Time.now.to_f, result.operation.to_s, result.msg_id, result.context_id, result.to_s.gsub("\n",''))
|
57
|
+
MPMessage.inject(Time.now.to_f, result.operation.to_s, result.msg_id, result.context_id, result.to_s.gsub("\n",''))
|
58
58
|
end
|
59
|
-
result
|
59
|
+
result
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -112,10 +112,10 @@ module OmfCommon
|
|
112
112
|
end
|
113
113
|
else
|
114
114
|
if key.nil?
|
115
|
-
value
|
115
|
+
string_value(value)
|
116
116
|
else
|
117
117
|
n = Message.new(key)
|
118
|
-
n.add_child(value
|
118
|
+
n.add_child(string_value(value))
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
@@ -123,7 +123,17 @@ module OmfCommon
|
|
123
123
|
# Generate SHA1 of canonicalised xml and write into the ID attribute of the message
|
124
124
|
#
|
125
125
|
def sign
|
126
|
-
write_attr('msg_id',
|
126
|
+
write_attr('msg_id', SecureRandom.uuid)
|
127
|
+
write_attr('timestamp', Time.now.utc.iso8601)
|
128
|
+
canonical_msg = self.canonicalize
|
129
|
+
|
130
|
+
priv_key = OmfCommon::Key.instance.private_key
|
131
|
+
digest = OpenSSL::Digest::SHA512.new(canonical_msg)
|
132
|
+
|
133
|
+
signature = Base64.encode64(priv_key.sign(digest, canonical_msg)).encode('utf-8') if priv_key
|
134
|
+
write_attr('digest', digest)
|
135
|
+
write_attr('signature', signature) if signature
|
136
|
+
|
127
137
|
if OmfCommon::Measure.enabled?
|
128
138
|
MPMessage.inject(Time.now.to_f, operation.to_s, msg_id, context_id, self.to_s.gsub("\n",''))
|
129
139
|
@@msg_id_list << msg_id
|
@@ -141,7 +151,7 @@ module OmfCommon
|
|
141
151
|
# Validate against relaxng schema
|
142
152
|
#
|
143
153
|
def valid?
|
144
|
-
validation =
|
154
|
+
validation = RelaxNGSchema.instance.schema.validate(self.document)
|
145
155
|
if validation.empty?
|
146
156
|
true
|
147
157
|
else
|
@@ -171,7 +181,7 @@ module OmfCommon
|
|
171
181
|
|
172
182
|
# Short cut for grabbing a group of nodes using xpath, but with default namespace
|
173
183
|
def element_by_xpath_with_default_namespace(xpath_without_ns)
|
174
|
-
xpath(xpath_without_ns.gsub(/(
|
184
|
+
xpath(xpath_without_ns.gsub(/(^|\/{1,2})(\w+)/, '\1xmlns:\2'), :xmlns => OMF_NAMESPACE)
|
175
185
|
end
|
176
186
|
|
177
187
|
# In case you think method :element_by_xpath_with_default_namespace is too long
|
@@ -181,7 +191,7 @@ module OmfCommon
|
|
181
191
|
# We just want to know the content of an non-repeatable element
|
182
192
|
#
|
183
193
|
def read_content(element_name)
|
184
|
-
element_content = read_element("
|
194
|
+
element_content = read_element("#{element_name}").first.content rescue nil
|
185
195
|
unless element_content.nil?
|
186
196
|
element_content.empty? ? nil : element_content
|
187
197
|
else
|
@@ -212,35 +222,42 @@ module OmfCommon
|
|
212
222
|
# @param [String] key name of the property element
|
213
223
|
# @return [Object] the content of the property, as string, integer, float, or mash(hash with indifferent access)
|
214
224
|
#
|
215
|
-
def read_property(key)
|
225
|
+
def read_property(key, data_binding = nil)
|
216
226
|
key = key.to_s
|
217
|
-
e = read_element("
|
218
|
-
reconstruct_data(e) if e
|
227
|
+
e = read_element("property[@key='#{key}']").first
|
228
|
+
reconstruct_data(e, data_binding) if e
|
219
229
|
end
|
220
230
|
|
221
|
-
def reconstruct_data(node)
|
222
|
-
|
231
|
+
def reconstruct_data(node, data_binding = nil)
|
232
|
+
node_type = node.attr('type')
|
233
|
+
case node_type
|
223
234
|
when 'array'
|
224
235
|
node.element_children.map do |child|
|
225
|
-
reconstruct_data(child)
|
236
|
+
reconstruct_data(child, data_binding)
|
226
237
|
end
|
227
238
|
when /hash/
|
228
239
|
mash ||= Hashie::Mash.new
|
229
240
|
node.element_children.each do |child|
|
230
|
-
mash[child.attr('key') || child.element_name] ||= reconstruct_data(child)
|
241
|
+
mash[child.attr('key') || child.element_name] ||= reconstruct_data(child, data_binding)
|
231
242
|
end
|
232
243
|
mash
|
233
244
|
when /boolean/
|
234
245
|
node.content == "true"
|
235
246
|
else
|
236
|
-
node.content.empty?
|
247
|
+
if node.content.empty?
|
248
|
+
nil
|
249
|
+
elsif data_binding && node_type == 'string'
|
250
|
+
ERB.new(node.content).result(data_binding)
|
251
|
+
else
|
252
|
+
node.content.ducktype
|
253
|
+
end
|
237
254
|
end
|
238
255
|
end
|
239
256
|
|
240
257
|
# Iterate each property element
|
241
258
|
#
|
242
259
|
def each_property(&block)
|
243
|
-
read_element("
|
260
|
+
read_element("property").each { |v| block.call(v) }
|
244
261
|
end
|
245
262
|
|
246
263
|
# Pretty print for application event message
|
@@ -253,11 +270,24 @@ module OmfCommon
|
|
253
270
|
|
254
271
|
def ruby_type_2_prop_type(ruby_class_type)
|
255
272
|
v_type = ruby_class_type.to_s.downcase
|
256
|
-
|
273
|
+
case v_type
|
274
|
+
when *%w(trueclass falseclass)
|
257
275
|
'boolean'
|
276
|
+
when *%w(fixnum bignum)
|
277
|
+
'integer'
|
258
278
|
else
|
259
279
|
v_type
|
260
280
|
end
|
261
281
|
end
|
282
|
+
|
283
|
+
# Get string of a value object, escape if object is string
|
284
|
+
def string_value(value)
|
285
|
+
if value.kind_of? String
|
286
|
+
value = CGI::escape_html(value)
|
287
|
+
else
|
288
|
+
value = value.to_s
|
289
|
+
end
|
290
|
+
value
|
291
|
+
end
|
262
292
|
end
|
263
293
|
end
|
@@ -1,61 +1,48 @@
|
|
1
|
-
default namespace = "http://schema.mytestbed.net/6.0/protocol"
|
1
|
+
default namespace = "http://schema.mytestbed.net/omf/6.0/protocol"
|
2
2
|
|
3
3
|
start = (create | configure | request | release | inform)
|
4
4
|
|
5
|
+
common_elements = attribute msg_id { text }, attribute timestamp { text }, attribute digest { text }, attribute signature { text }?
|
6
|
+
|
5
7
|
anything = ( text | element * { (attribute type { text })?, (text | anything) * })
|
6
8
|
|
9
|
+
prop_content = attribute key { text }, (attribute type { text })?, anything *
|
10
|
+
|
7
11
|
create = element create {
|
8
|
-
|
9
|
-
element
|
10
|
-
element property {
|
11
|
-
|
12
|
-
(attribute type { text })?,
|
13
|
-
anything *
|
14
|
-
} *
|
12
|
+
common_elements
|
13
|
+
& element publish_to { text }?
|
14
|
+
& element guard { element property { prop_content } * }?
|
15
|
+
& element property { prop_content } *
|
15
16
|
}
|
16
17
|
|
17
18
|
configure = element configure {
|
18
|
-
|
19
|
-
element
|
20
|
-
element property {
|
21
|
-
|
22
|
-
(attribute type { text })?,
|
23
|
-
anything *
|
24
|
-
} *
|
19
|
+
common_elements
|
20
|
+
& element publish_to { text }?
|
21
|
+
& element guard { element property { prop_content } * }?
|
22
|
+
& element property { prop_content } *
|
25
23
|
}
|
26
24
|
|
27
25
|
request = element request {
|
28
|
-
|
29
|
-
element
|
30
|
-
element
|
31
|
-
element property {
|
32
|
-
(attribute key { text }),
|
33
|
-
(attribute type { text })?,
|
34
|
-
anything *
|
35
|
-
}*
|
26
|
+
common_elements
|
27
|
+
& element publish_to { text }?
|
28
|
+
& element guard { element property { prop_content } * }?
|
29
|
+
& element property { prop_content } *
|
36
30
|
}
|
37
31
|
|
38
32
|
release = element release {
|
39
|
-
|
40
|
-
element
|
41
|
-
element resource_id { text }
|
42
|
-
element property {
|
43
|
-
|
44
|
-
(attribute type { text })?,
|
45
|
-
anything *
|
46
|
-
}*
|
33
|
+
common_elements
|
34
|
+
& element publish_to { text }?
|
35
|
+
& element resource_id { text }
|
36
|
+
& element guard { element property { prop_content } * }?
|
37
|
+
& element property { prop_content } *
|
47
38
|
}
|
48
39
|
|
49
40
|
inform = element inform {
|
50
|
-
|
51
|
-
element context_id { text }
|
52
|
-
element inform_type { "CREATED" | "FAILED" | "STATUS" | "RELEASED" | "ERROR" | "WARN"}
|
53
|
-
element resource_id { text }
|
54
|
-
element resource_address { text }
|
55
|
-
element reason { text }
|
56
|
-
element property {
|
57
|
-
attribute key { text },
|
58
|
-
(attribute type { text })?,
|
59
|
-
anything *
|
60
|
-
} *
|
41
|
+
common_elements
|
42
|
+
& element context_id { text }?
|
43
|
+
& element inform_type { "CREATED" | "FAILED" | "STATUS" | "RELEASED" | "ERROR" | "WARN"}
|
44
|
+
& element resource_id { text }?
|
45
|
+
& element resource_address { text }?
|
46
|
+
& element reason { text }?
|
47
|
+
& element property { prop_content } *
|
61
48
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<grammar ns="http://schema.mytestbed.net/6.0/protocol" xmlns="http://relaxng.org/ns/structure/1.0">
|
2
|
+
<grammar ns="http://schema.mytestbed.net/omf/6.0/protocol" xmlns="http://relaxng.org/ns/structure/1.0">
|
3
3
|
<start>
|
4
4
|
<choice>
|
5
5
|
<ref name="create"/>
|
@@ -9,6 +9,14 @@
|
|
9
9
|
<ref name="inform"/>
|
10
10
|
</choice>
|
11
11
|
</start>
|
12
|
+
<define name="common_elements">
|
13
|
+
<attribute name="msg_id"/>
|
14
|
+
<attribute name="timestamp"/>
|
15
|
+
<attribute name="digest"/>
|
16
|
+
<optional>
|
17
|
+
<attribute name="signature"/>
|
18
|
+
</optional>
|
19
|
+
</define>
|
12
20
|
<define name="anything">
|
13
21
|
<choice>
|
14
22
|
<text/>
|
@@ -26,132 +34,162 @@
|
|
26
34
|
</element>
|
27
35
|
</choice>
|
28
36
|
</define>
|
37
|
+
<define name="prop_content">
|
38
|
+
<attribute name="key"/>
|
39
|
+
<optional>
|
40
|
+
<attribute name="type"/>
|
41
|
+
</optional>
|
42
|
+
<zeroOrMore>
|
43
|
+
<ref name="anything"/>
|
44
|
+
</zeroOrMore>
|
45
|
+
</define>
|
29
46
|
<define name="create">
|
30
47
|
<element name="create">
|
31
|
-
<
|
32
|
-
|
33
|
-
<
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
<interleave>
|
49
|
+
<ref name="common_elements"/>
|
50
|
+
<optional>
|
51
|
+
<element name="publish_to">
|
52
|
+
<text/>
|
53
|
+
</element>
|
54
|
+
</optional>
|
55
|
+
<optional>
|
56
|
+
<element name="guard">
|
57
|
+
<zeroOrMore>
|
58
|
+
<element name="property">
|
59
|
+
<ref name="prop_content"/>
|
60
|
+
</element>
|
61
|
+
</zeroOrMore>
|
62
|
+
</element>
|
63
|
+
</optional>
|
64
|
+
<zeroOrMore>
|
65
|
+
<element name="property">
|
66
|
+
<ref name="prop_content"/>
|
67
|
+
</element>
|
68
|
+
</zeroOrMore>
|
69
|
+
</interleave>
|
46
70
|
</element>
|
47
71
|
</define>
|
48
72
|
<define name="configure">
|
49
73
|
<element name="configure">
|
50
|
-
<
|
51
|
-
|
52
|
-
<
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
74
|
+
<interleave>
|
75
|
+
<ref name="common_elements"/>
|
76
|
+
<optional>
|
77
|
+
<element name="publish_to">
|
78
|
+
<text/>
|
79
|
+
</element>
|
80
|
+
</optional>
|
81
|
+
<optional>
|
82
|
+
<element name="guard">
|
83
|
+
<zeroOrMore>
|
84
|
+
<element name="property">
|
85
|
+
<ref name="prop_content"/>
|
86
|
+
</element>
|
87
|
+
</zeroOrMore>
|
88
|
+
</element>
|
89
|
+
</optional>
|
90
|
+
<zeroOrMore>
|
91
|
+
<element name="property">
|
92
|
+
<ref name="prop_content"/>
|
93
|
+
</element>
|
94
|
+
</zeroOrMore>
|
95
|
+
</interleave>
|
65
96
|
</element>
|
66
97
|
</define>
|
67
98
|
<define name="request">
|
68
99
|
<element name="request">
|
69
|
-
<
|
70
|
-
|
71
|
-
<
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
</
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
100
|
+
<interleave>
|
101
|
+
<ref name="common_elements"/>
|
102
|
+
<optional>
|
103
|
+
<element name="publish_to">
|
104
|
+
<text/>
|
105
|
+
</element>
|
106
|
+
</optional>
|
107
|
+
<optional>
|
108
|
+
<element name="guard">
|
109
|
+
<zeroOrMore>
|
110
|
+
<element name="property">
|
111
|
+
<ref name="prop_content"/>
|
112
|
+
</element>
|
113
|
+
</zeroOrMore>
|
114
|
+
</element>
|
115
|
+
</optional>
|
116
|
+
<zeroOrMore>
|
117
|
+
<element name="property">
|
118
|
+
<ref name="prop_content"/>
|
119
|
+
</element>
|
120
|
+
</zeroOrMore>
|
121
|
+
</interleave>
|
89
122
|
</element>
|
90
123
|
</define>
|
91
124
|
<define name="release">
|
92
125
|
<element name="release">
|
93
|
-
<
|
94
|
-
|
95
|
-
<
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
<attribute name="key"/>
|
103
|
-
<optional>
|
104
|
-
<attribute name="type"/>
|
105
|
-
</optional>
|
106
|
-
<zeroOrMore>
|
107
|
-
<ref name="anything"/>
|
108
|
-
</zeroOrMore>
|
126
|
+
<interleave>
|
127
|
+
<ref name="common_elements"/>
|
128
|
+
<optional>
|
129
|
+
<element name="publish_to">
|
130
|
+
<text/>
|
131
|
+
</element>
|
132
|
+
</optional>
|
133
|
+
<element name="resource_id">
|
134
|
+
<text/>
|
109
135
|
</element>
|
110
|
-
|
136
|
+
<optional>
|
137
|
+
<element name="guard">
|
138
|
+
<zeroOrMore>
|
139
|
+
<element name="property">
|
140
|
+
<ref name="prop_content"/>
|
141
|
+
</element>
|
142
|
+
</zeroOrMore>
|
143
|
+
</element>
|
144
|
+
</optional>
|
145
|
+
<zeroOrMore>
|
146
|
+
<element name="property">
|
147
|
+
<ref name="prop_content"/>
|
148
|
+
</element>
|
149
|
+
</zeroOrMore>
|
150
|
+
</interleave>
|
111
151
|
</element>
|
112
152
|
</define>
|
113
153
|
<define name="inform">
|
114
154
|
<element name="inform">
|
115
|
-
<
|
116
|
-
|
117
|
-
<
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
<
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
<text/>
|
132
|
-
</element>
|
133
|
-
</optional>
|
134
|
-
<optional>
|
135
|
-
<element name="resource_address">
|
136
|
-
<text/>
|
137
|
-
</element>
|
138
|
-
</optional>
|
139
|
-
<optional>
|
140
|
-
<element name="reason">
|
141
|
-
<text/>
|
142
|
-
</element>
|
143
|
-
</optional>
|
144
|
-
<zeroOrMore>
|
145
|
-
<element name="property">
|
146
|
-
<attribute name="key"/>
|
147
|
-
<optional>
|
148
|
-
<attribute name="type"/>
|
149
|
-
</optional>
|
150
|
-
<zeroOrMore>
|
151
|
-
<ref name="anything"/>
|
152
|
-
</zeroOrMore>
|
155
|
+
<interleave>
|
156
|
+
<ref name="common_elements"/>
|
157
|
+
<optional>
|
158
|
+
<element name="context_id">
|
159
|
+
<text/>
|
160
|
+
</element>
|
161
|
+
</optional>
|
162
|
+
<element name="inform_type">
|
163
|
+
<choice>
|
164
|
+
<value>CREATED</value>
|
165
|
+
<value>FAILED</value>
|
166
|
+
<value>STATUS</value>
|
167
|
+
<value>RELEASED</value>
|
168
|
+
<value>ERROR</value>
|
169
|
+
<value>WARN</value>
|
170
|
+
</choice>
|
153
171
|
</element>
|
154
|
-
|
172
|
+
<optional>
|
173
|
+
<element name="resource_id">
|
174
|
+
<text/>
|
175
|
+
</element>
|
176
|
+
</optional>
|
177
|
+
<optional>
|
178
|
+
<element name="resource_address">
|
179
|
+
<text/>
|
180
|
+
</element>
|
181
|
+
</optional>
|
182
|
+
<optional>
|
183
|
+
<element name="reason">
|
184
|
+
<text/>
|
185
|
+
</element>
|
186
|
+
</optional>
|
187
|
+
<zeroOrMore>
|
188
|
+
<element name="property">
|
189
|
+
<ref name="prop_content"/>
|
190
|
+
</element>
|
191
|
+
</zeroOrMore>
|
192
|
+
</interleave>
|
155
193
|
</element>
|
156
194
|
</define>
|
157
195
|
</grammar>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module OmfCommon
|
4
|
+
class RelaxNGSchema
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
SCHEMA_FILE = "#{File.dirname(__FILE__)}/protocol/#{OmfCommon::PROTOCOL_VERSION}.rng"
|
8
|
+
|
9
|
+
attr_accessor :schema
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
File.open(SCHEMA_FILE) do |f|
|
13
|
+
self.schema = Nokogiri::XML::RelaxNG(f.read)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/omf_common/topic.rb
CHANGED
data/lib/omf_common/version.rb
CHANGED
data/omf_common.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_development_dependency "em-minitest-spec", "~> 1.1.1"
|
24
24
|
s.add_development_dependency "simplecov"
|
25
25
|
s.add_runtime_dependency "eventmachine", "~> 0.12.10"
|
26
|
-
s.add_runtime_dependency "blather", "
|
26
|
+
s.add_runtime_dependency "blather", "= 0.8.0"
|
27
27
|
s.add_runtime_dependency "logging", "~> 1.7.1"
|
28
28
|
s.add_runtime_dependency "hashie", "~> 1.2.0"
|
29
29
|
s.add_runtime_dependency "oml4r", "~> 2.8.0"
|
data/test/fixture/pubsub.rb
CHANGED
@@ -172,7 +172,7 @@ def omf_created_xml
|
|
172
172
|
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
173
173
|
<items node="mclaren">
|
174
174
|
<item id="4JMgcKzxFDLsP74">
|
175
|
-
<inform xmlns="http://schema.mytestbed.net/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
175
|
+
<inform xmlns="http://schema.mytestbed.net/omf/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
176
176
|
<context_id>bf840fe9-c176-4fae-b7de-6fc27f183f76</context_id>
|
177
177
|
<inform_type>CREATED</inform_type>
|
178
178
|
<resource_id>444f17fb-546e-4685-a0d0-63e64fa046c8</resource_id>
|
@@ -194,7 +194,7 @@ def omf_status_xml
|
|
194
194
|
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
195
195
|
<items node="mclaren">
|
196
196
|
<item id="4JMgcKzxFDLsP74">
|
197
|
-
<inform xmlns="http://schema.mytestbed.net/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
197
|
+
<inform xmlns="http://schema.mytestbed.net/omf/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
198
198
|
<context_id>bf840fe9-c176-4fae-b7de-6fc27f183f76</context_id>
|
199
199
|
<inform_type>STATUS</inform_type>
|
200
200
|
<property key="bob">bob</property>
|
@@ -215,7 +215,7 @@ def omf_failed_xml
|
|
215
215
|
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
216
216
|
<items node="mclaren">
|
217
217
|
<item id="4JMgcKzxFDLsP74">
|
218
|
-
<inform xmlns="http://schema.mytestbed.net/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
218
|
+
<inform xmlns="http://schema.mytestbed.net/omf/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
219
219
|
<context_id>bf840fe9-c176-4fae-b7de-6fc27f183f76</context_id>
|
220
220
|
<inform_type>FAILED</inform_type>
|
221
221
|
<reason>No idea</reason>
|
@@ -236,7 +236,7 @@ def omf_released_xml
|
|
236
236
|
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
237
237
|
<items node="mclaren">
|
238
238
|
<item id="4JMgcKzxFDLsP74">
|
239
|
-
<inform xmlns="http://schema.mytestbed.net/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
239
|
+
<inform xmlns="http://schema.mytestbed.net/omf/6.0/protocol" msg_id="a2b6aba9f11dc5bb88306a32d0720641f5020c1f">
|
240
240
|
<context_id>bf840fe9-c176-4fae-b7de-6fc27f183f76</context_id>
|
241
241
|
<inform_type>RELEASED</inform_type>
|
242
242
|
<resource_id>444f17fb-546e-4685-a0d0-63e64fa046c8</resource_id>
|
@@ -8,7 +8,7 @@ describe OmfCommon::DSL::Xmpp do
|
|
8
8
|
@stream = MiniTest::Mock.new
|
9
9
|
@stream.expect(:send, true, [Blather::Stanza])
|
10
10
|
@client.post_init @stream, Blather::JID.new('n@d/r')
|
11
|
-
@xmpp =
|
11
|
+
@xmpp = OmfCommon::Comm.new(:xmpp)
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "when communicating to xmpp server (via mocking)" do
|
@@ -177,8 +177,8 @@ describe OmfCommon::DSL::Xmpp do
|
|
177
177
|
m1.must_be_kind_of OmfCommon::TopicMessage
|
178
178
|
m2.must_be_kind_of OmfCommon::TopicMessage
|
179
179
|
m1.body.name.must_equal 'configure'
|
180
|
-
m1.body.to_xml.must_match /<property key="throttle" type="
|
181
|
-
m2.body.to_xml.must_match /<property key="throttle" type="
|
180
|
+
m1.body.to_xml.must_match /<property key="throttle" type="integer">50<\/property>/
|
181
|
+
m2.body.to_xml.must_match /<property key="throttle" type="integer">50<\/property>/
|
182
182
|
end
|
183
183
|
|
184
184
|
it "must generate omf inform xml fragment" do
|
@@ -201,8 +201,8 @@ describe OmfCommon::DSL::Xmpp do
|
|
201
201
|
m1.must_be_kind_of OmfCommon::TopicMessage
|
202
202
|
m2.must_be_kind_of OmfCommon::TopicMessage
|
203
203
|
m1.body.name.must_equal 'release'
|
204
|
-
m1.body.to_xml.must_match /<property key="resource_id" type="
|
205
|
-
m2.body.to_xml.must_match /<property key="resource_id" type="
|
204
|
+
m1.body.to_xml.must_match /<property key="resource_id" type="integer">100<\/property>/
|
205
|
+
m2.body.to_xml.must_match /<property key="resource_id" type="integer">100<\/property>/
|
206
206
|
end
|
207
207
|
|
208
208
|
it "must generate omf request xml fragment" do
|
@@ -230,7 +230,7 @@ describe OmfCommon::DSL::Xmpp do
|
|
230
230
|
it "must react to omf created message" do
|
231
231
|
Blather::Client.stub :new, @client do
|
232
232
|
omf_create = OmfCommon::Message.create { |v| v.property('type', 'engine') }
|
233
|
-
omf_create.stub :
|
233
|
+
omf_create.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
234
234
|
omf_created = Blather::XMPPNode.parse(omf_created_xml)
|
235
235
|
@client.receive_data omf_created
|
236
236
|
@xmpp.on_created_message(omf_create) do |n|
|
@@ -245,7 +245,7 @@ describe OmfCommon::DSL::Xmpp do
|
|
245
245
|
it "must react to omf status message" do
|
246
246
|
Blather::Client.stub :new, @client do
|
247
247
|
omf_request = OmfCommon::Message.request { |v| v.property('bob') }
|
248
|
-
omf_request.stub :
|
248
|
+
omf_request.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
249
249
|
omf_status = Blather::XMPPNode.parse(omf_status_xml)
|
250
250
|
@client.receive_data omf_status
|
251
251
|
@xmpp.on_status_message(omf_request) do |n|
|
@@ -260,7 +260,7 @@ describe OmfCommon::DSL::Xmpp do
|
|
260
260
|
it "must react to omf release message" do
|
261
261
|
Blather::Client.stub :new, @client do
|
262
262
|
omf_release = OmfCommon::Message.release { |v| v.property('resource_id', '100') }
|
263
|
-
omf_release.stub :
|
263
|
+
omf_release.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
264
264
|
omf_released = Blather::XMPPNode.parse(omf_released_xml)
|
265
265
|
@client.receive_data omf_released
|
266
266
|
@xmpp.on_released_message(omf_release) do |n|
|
@@ -275,7 +275,7 @@ describe OmfCommon::DSL::Xmpp do
|
|
275
275
|
it "must react to omf failed message" do
|
276
276
|
Blather::Client.stub :new, @client do
|
277
277
|
omf_create = OmfCommon::Message.create { |v| v.property('type', 'engine') }
|
278
|
-
omf_create.stub :
|
278
|
+
omf_create.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
279
279
|
omf_failed = Blather::XMPPNode.parse(omf_failed_xml)
|
280
280
|
@client.receive_data omf_failed
|
281
281
|
@xmpp.on_failed_message(omf_create) do |n|
|
@@ -9,6 +9,7 @@ describe OmfCommon::Message do
|
|
9
9
|
it "must return a create or configure XML element without failing" do
|
10
10
|
%w(create configure).each do |msg_name|
|
11
11
|
message = Message.__send__(msg_name) do |m|
|
12
|
+
|
12
13
|
PROP_ELEMENTS.each_with_index do |prop_element, index|
|
13
14
|
if index == 0
|
14
15
|
m.property(prop_element, rand(100))
|
@@ -17,8 +18,15 @@ describe OmfCommon::Message do
|
|
17
18
|
p.element('unit', 'test')
|
18
19
|
p.element('precision', 'test')
|
19
20
|
end
|
21
|
+
|
20
22
|
end
|
21
23
|
end
|
24
|
+
|
25
|
+
# Guard element optional
|
26
|
+
m.element(:guard) do |g|
|
27
|
+
g.property('p1', 1)
|
28
|
+
g.property('p2', 2)
|
29
|
+
end
|
22
30
|
end
|
23
31
|
message.valid?.must_equal true
|
24
32
|
end
|
@@ -57,6 +65,17 @@ describe OmfCommon::Message do
|
|
57
65
|
m.context_id.must_equal '9012c3bc-68de-459a-ac9f-530cc7168e22'
|
58
66
|
end
|
59
67
|
|
68
|
+
it "must escape erb code in property" do
|
69
|
+
m = Message.inform('CREATED', '9012c3bc-68de-459a-ac9f-530cc7168e22') do |m|
|
70
|
+
m.property('bob', "hello <%= world %>")
|
71
|
+
m.property('alice', "hello <%= 1 % 2 %>")
|
72
|
+
end
|
73
|
+
m.read_property('bob').must_equal "hello <%= world %>"
|
74
|
+
world = 'world'
|
75
|
+
m.read_property('bob', binding).must_equal "hello world"
|
76
|
+
m.read_property('alice', binding).must_equal "hello 1"
|
77
|
+
end
|
78
|
+
|
60
79
|
it "must be able to pretty print an app_event message" do
|
61
80
|
Message.inform('STATUS') do |m|
|
62
81
|
m.property('status_type', 'APP_EVENT')
|
@@ -84,9 +103,9 @@ describe OmfCommon::Message do
|
|
84
103
|
|
85
104
|
message.must_be_kind_of Message
|
86
105
|
message.operation.must_equal :create
|
87
|
-
message.read_element("
|
88
|
-
message.read_content("unit").must_equal 'mb'
|
89
|
-
message.read_element("
|
106
|
+
message.read_element("property").size.must_equal 7
|
107
|
+
message.read_content("property[@key='memory']/unit").must_equal 'mb'
|
108
|
+
message.read_element("property").size.must_equal 7
|
90
109
|
message.read_property("type").must_equal 'vm'
|
91
110
|
message.read_property(:type).must_equal 'vm'
|
92
111
|
|
@@ -10,7 +10,7 @@ describe OmfCommon::Topic do
|
|
10
10
|
@stream = MiniTest::Mock.new
|
11
11
|
@stream.expect(:send, true, [Blather::Stanza])
|
12
12
|
@client.post_init @stream, Blather::JID.new('n@d/r')
|
13
|
-
@comm =
|
13
|
+
@comm = Comm.new(:xmpp)
|
14
14
|
@topic = @comm.get_topic('mclaren')
|
15
15
|
@message = @comm.request_message([:bob])
|
16
16
|
end
|
@@ -50,7 +50,7 @@ describe OmfCommon::Topic do
|
|
50
50
|
it "must react to omf created message" do
|
51
51
|
Blather::Client.stub :new, @client do
|
52
52
|
omf_create = @comm.create_message { |v| v.property('type', 'engine') }
|
53
|
-
omf_create.body.stub :
|
53
|
+
omf_create.body.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
54
54
|
omf_created = Blather::XMPPNode.parse(omf_created_xml)
|
55
55
|
@client.receive_data omf_created
|
56
56
|
omf_create.on_inform_created do |n|
|
@@ -66,7 +66,7 @@ describe OmfCommon::Topic do
|
|
66
66
|
it "must react to omf status message" do
|
67
67
|
Blather::Client.stub :new, @client do
|
68
68
|
omf_request = @comm.request_message { |v| v.property('bob') }
|
69
|
-
omf_request.body.stub :
|
69
|
+
omf_request.body.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
70
70
|
omf_status = Blather::XMPPNode.parse(omf_status_xml)
|
71
71
|
@client.receive_data omf_status
|
72
72
|
omf_request.on_inform_status do |n|
|
@@ -82,7 +82,7 @@ describe OmfCommon::Topic do
|
|
82
82
|
it "must react to omf release message" do
|
83
83
|
Blather::Client.stub :new, @client do
|
84
84
|
omf_release = @comm.release_message { |v| v.property('resource_id', '100') }
|
85
|
-
omf_release.body.stub :
|
85
|
+
omf_release.body.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
86
86
|
omf_released = Blather::XMPPNode.parse(omf_released_xml)
|
87
87
|
@client.receive_data omf_released
|
88
88
|
omf_release.on_inform_released do |n|
|
@@ -98,7 +98,7 @@ describe OmfCommon::Topic do
|
|
98
98
|
it "must react to omf failed message" do
|
99
99
|
Blather::Client.stub :new, @client do
|
100
100
|
omf_create = @comm.create_message { |v| v.property('type', 'engine') }
|
101
|
-
omf_create.body.stub :
|
101
|
+
omf_create.body.stub :msg_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
102
102
|
omf_failed = Blather::XMPPNode.parse(omf_failed_xml)
|
103
103
|
@client.receive_data omf_failed
|
104
104
|
omf_create.on_inform_failed do |n|
|
@@ -10,7 +10,7 @@ describe OmfCommon::Topic do
|
|
10
10
|
@stream = MiniTest::Mock.new
|
11
11
|
@stream.expect(:send, true, [Blather::Stanza])
|
12
12
|
@client.post_init @stream, Blather::JID.new('n@d/r')
|
13
|
-
@comm =
|
13
|
+
@comm = Comm.new(:xmpp)
|
14
14
|
@topic = @comm.get_topic('mclaren')
|
15
15
|
end
|
16
16
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omf_common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0.pre.
|
4
|
+
version: 6.0.0.pre.10
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
83
|
-
- -
|
83
|
+
- - '='
|
84
84
|
- !ruby/object:Gem::Version
|
85
85
|
version: 0.8.0
|
86
86
|
type: :runtime
|
@@ -88,7 +88,7 @@ dependencies:
|
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
91
|
-
- -
|
91
|
+
- - '='
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: 0.8.0
|
94
94
|
- !ruby/object:Gem::Dependency
|
@@ -155,13 +155,16 @@ files:
|
|
155
155
|
- lib/omf_common/command.rb
|
156
156
|
- lib/omf_common/core_ext/object.rb
|
157
157
|
- lib/omf_common/core_ext/string.rb
|
158
|
+
- lib/omf_common/default_logging.rb
|
158
159
|
- lib/omf_common/dsl/xmpp.rb
|
159
160
|
- lib/omf_common/dsl/xmpp_mp.rb
|
160
161
|
- lib/omf_common/exec_app.rb
|
162
|
+
- lib/omf_common/key.rb
|
161
163
|
- lib/omf_common/measure.rb
|
162
164
|
- lib/omf_common/message.rb
|
163
165
|
- lib/omf_common/protocol/6.0.rnc
|
164
166
|
- lib/omf_common/protocol/6.0.rng
|
167
|
+
- lib/omf_common/relaxng_schema.rb
|
165
168
|
- lib/omf_common/topic.rb
|
166
169
|
- lib/omf_common/topic_message.rb
|
167
170
|
- lib/omf_common/version.rb
|
@@ -199,4 +202,13 @@ rubygems_version: 1.8.24
|
|
199
202
|
signing_key:
|
200
203
|
specification_version: 3
|
201
204
|
summary: Common library of OMF
|
202
|
-
test_files:
|
205
|
+
test_files:
|
206
|
+
- test/fixture/pubsub.rb
|
207
|
+
- test/omf_common/comm_spec.rb
|
208
|
+
- test/omf_common/command_spec.rb
|
209
|
+
- test/omf_common/core_ext/string_spec.rb
|
210
|
+
- test/omf_common/dsl/xmpp_spec.rb
|
211
|
+
- test/omf_common/message_spec.rb
|
212
|
+
- test/omf_common/topic_message_spec.rb
|
213
|
+
- test/omf_common/topic_spec.rb
|
214
|
+
- test/test_helper.rb
|