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.
@@ -1,25 +1,17 @@
1
- require 'logging'
2
- require 'active_support/inflector'
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 "omf_common/message"
7
- require "omf_common/comm"
8
- require "omf_common/command"
9
- require "omf_common/topic"
10
- require "omf_common/topic_message"
11
- require "omf_common/core_ext/string"
12
- require "omf_common/core_ext/object"
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
- Logging.appenders.stdout('stdout',
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
@@ -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
@@ -27,8 +27,31 @@ module OmfCommon
27
27
  end
28
28
 
29
29
  # Shut down XMPP connection
30
- def disconnect
31
- shutdown
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
- def subscribe(topic, &block)
53
- pubsub.subscribe(topic, nil, default_host, &callback_logging(__method__, topic, &block))
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
- OmfCommon::TopicMessage.new(message, self)
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
- passed
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 |callback|
155
- logger.error callback if callback.respond_to?(:error?) && callback.error?
156
- logger.debug "#{m} SUCCEED" if callback.respond_to?(:result?) && callback.result?
157
- block.call(callback) if block
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
 
@@ -0,0 +1,14 @@
1
+ require 'openssl'
2
+ require 'singleton'
3
+
4
+ module OmfCommon
5
+ class Key
6
+ include Singleton
7
+
8
+ attr_accessor :private_key
9
+
10
+ def import(filename)
11
+ self.private_key = OpenSSL::PKey.read(File.read(filename))
12
+ end
13
+ end
14
+ end
@@ -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] || SecureRandom.uuid)
42
+ xml.element('context_id', args[1]) if args[1]
42
43
  xml.element('inform_type', args[0])
43
44
  else
44
- xml.element('context_id', SecureRandom.uuid)
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.to_s
115
+ string_value(value)
116
116
  else
117
117
  n = Message.new(key)
118
- n.add_child(value.to_s)
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', OpenSSL::Digest::SHA1.new(canonicalize)) if read_attr('id').nil? || read_attr('id').empty?
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 = Nokogiri::XML::RelaxNG(File.open(SCHEMA_FILE)).validate(self.document)
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(/(\/+)(\w+)/, '\1xmlns:\2'), :xmlns => OMF_NAMESPACE)
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("//#{element_name}").first.content rescue nil
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("//property[@key='#{key}']").first
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
- case node.attr('type')
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? ? nil : node.content.ducktype
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("//property").each { |v| block.call(v) }
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
- if %w(trueclass falseclass).include?(v_type)
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
- attribute msg_id { text },
9
- element context_id { text },
10
- element property {
11
- attribute key { text },
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
- attribute msg_id { text },
19
- element context_id { text },
20
- element property {
21
- attribute key { text },
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
- attribute msg_id { text },
29
- element context_id { text },
30
- element publish_to { text }?,
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
- attribute msg_id { text },
40
- element context_id { text },
41
- element resource_id { text },
42
- element property {
43
- (attribute key { text }),
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
- attribute msg_id { text },
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
- <attribute name="msg_id"/>
32
- <element name="context_id">
33
- <text/>
34
- </element>
35
- <zeroOrMore>
36
- <element name="property">
37
- <attribute name="key"/>
38
- <optional>
39
- <attribute name="type"/>
40
- </optional>
41
- <zeroOrMore>
42
- <ref name="anything"/>
43
- </zeroOrMore>
44
- </element>
45
- </zeroOrMore>
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
- <attribute name="msg_id"/>
51
- <element name="context_id">
52
- <text/>
53
- </element>
54
- <zeroOrMore>
55
- <element name="property">
56
- <attribute name="key"/>
57
- <optional>
58
- <attribute name="type"/>
59
- </optional>
60
- <zeroOrMore>
61
- <ref name="anything"/>
62
- </zeroOrMore>
63
- </element>
64
- </zeroOrMore>
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
- <attribute name="msg_id"/>
70
- <element name="context_id">
71
- <text/>
72
- </element>
73
- <optional>
74
- <element name="publish_to">
75
- <text/>
76
- </element>
77
- </optional>
78
- <zeroOrMore>
79
- <element name="property">
80
- <attribute name="key"/>
81
- <optional>
82
- <attribute name="type"/>
83
- </optional>
84
- <zeroOrMore>
85
- <ref name="anything"/>
86
- </zeroOrMore>
87
- </element>
88
- </zeroOrMore>
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
- <attribute name="msg_id"/>
94
- <element name="context_id">
95
- <text/>
96
- </element>
97
- <element name="resource_id">
98
- <text/>
99
- </element>
100
- <zeroOrMore>
101
- <element name="property">
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
- </zeroOrMore>
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
- <attribute name="msg_id"/>
116
- <element name="context_id">
117
- <text/>
118
- </element>
119
- <element name="inform_type">
120
- <choice>
121
- <value>CREATED</value>
122
- <value>FAILED</value>
123
- <value>STATUS</value>
124
- <value>RELEASED</value>
125
- <value>ERROR</value>
126
- <value>WARN</value>
127
- </choice>
128
- </element>
129
- <optional>
130
- <element name="resource_id">
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
- </zeroOrMore>
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
@@ -22,7 +22,7 @@ module OmfCommon
22
22
  event.node == self.id &&
23
23
  (valid_guard?(message_guard_proc) ? message_guard_proc.call(omf_message) : true)
24
24
  end
25
- comm.pubsub_event(guard_block, &event_block)
25
+ comm.topic_event(guard_block, &event_block)
26
26
  end
27
27
 
28
28
  private
@@ -1,4 +1,4 @@
1
1
  module OmfCommon
2
- VERSION = "6.0.0.pre.8"
2
+ VERSION = "6.0.0.pre.10"
3
3
  PROTOCOL_VERSION = "6.0"
4
4
  end
@@ -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", "~> 0.8.0"
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"
@@ -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 = Class.new { include OmfCommon::DSL::Xmpp }.new
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="fixnum">50<\/property>/
181
- m2.body.to_xml.must_match /<property key="throttle" type="fixnum">50<\/property>/
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="fixnum">100<\/property>/
205
- m2.body.to_xml.must_match /<property key="resource_id" type="fixnum">100<\/property>/
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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("//property").size.must_equal 7
88
- message.read_content("unit").must_equal 'mb'
89
- message.read_element("/create/property").size.must_equal 7
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 = Class.new { include OmfCommon::DSL::Xmpp }.new
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
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 = Class.new { include OmfCommon::DSL::Xmpp }.new
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.8
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: 2012-10-26 00:00:00.000000000 Z
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