omf_common 6.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in omf_common.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake/testtask'
2
+ require "bundler/gem_tasks"
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ t.pattern = "test/**/*_spec.rb"
9
+ t.verbose = true
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'omf_common/dsl/xmpp_blather'
2
+
3
+ module OmfCommon
4
+ class Comm
5
+ def initialize(pubsub_implementation)
6
+ self.extend("OmfCommon::DSL::#{pubsub_implementation.to_s.camelcase}".constant)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ require 'open3'
2
+
3
+ module OmfCommon::Command
4
+ # Execute a system command and use Open3 to capture exit status, stdout, stderr
5
+ #
6
+ # @example
7
+ #
8
+ # OmfRc::Command.execute("uname -a")
9
+ def self.execute(*cmd, &block)
10
+ result = nil
11
+ begin
12
+ Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thread|
13
+ case wait_thread.value.exitstatus
14
+ when 0
15
+ # Exit status 0, all good, read stdout
16
+ result = stdout.read.chomp
17
+ when 1
18
+ # Exit status 1, log minor error as warning
19
+ logger.warn stderr.read.chomp
20
+ when 2
21
+ # Exit status 2, log standard error
22
+ logger.error stderr.read.chomp
23
+ else
24
+ # Exit status greater than 2, log fatal error
25
+ logger.fatal stderr.read.chomp
26
+ end
27
+ end
28
+ rescue Errno::ENOENT => e
29
+ logger.fatal e.message
30
+ end
31
+ result
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module Blather
2
+ module DSL
3
+ class PubSub
4
+ def create_with_configuration(node, configuration, host = nil)
5
+ stanza = Stanza::PubSub::Create.new(:set, send_to(host), node)
6
+ stanza.configure_node << configuration
7
+ request(stanza) { |n| yield n if block_given? }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module Blather
2
+ module DSL
3
+ def register(username, password, &block)
4
+ stanza = Blather::Stanza::Registration.new(username, password)
5
+ client.write_with_handler(stanza, &block)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ require 'blather/stanza/iq'
2
+
3
+ module Blather
4
+ class Stanza
5
+ class Registration < Iq
6
+ def self.new(username, password)
7
+ node = super :set
8
+ Nokogiri::XML::Builder.with(node) do |xml|
9
+ xml.query('xmlns' => 'jabber:iq:register') do
10
+ xml.username username
11
+ xml.password password
12
+ end
13
+ end
14
+ node
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+ def ducktype
3
+ Integer(self) rescue Float(self) rescue self
4
+ end
5
+
6
+ def camelcase
7
+ self.split('_').map(&:capitalize).join('')
8
+ end
9
+
10
+ def constant
11
+ self.split('::').inject(Object) { |obj, name| obj = obj.const_get(name); obj }
12
+ end
13
+ end
@@ -0,0 +1,99 @@
1
+ require 'blather/client/dsl'
2
+ require 'omf_common/core_ext/blather/dsl'
3
+ require 'omf_common/core_ext/blather/dsl/pubsub'
4
+ require 'omf_common/core_ext/blather/stanza/registration'
5
+
6
+ module OmfCommon
7
+ module DSL
8
+ module XmppBlather
9
+ include Blather::DSL
10
+
11
+ PUBSUB_CONFIGURE = Blather::Stanza::X.new({
12
+ :type => :submit,
13
+ :fields => [
14
+ { :var => "FORM_TYPE", :type => 'hidden', :value => "http://jabber.org/protocol/pubsub#node_config" },
15
+ { :var => "pubsub#persist_items", :value => "0" },
16
+ { :var => "pubsub#max_items", :value => "0" },
17
+ { :var => "pubsub#notify_retract", :value => "0" },
18
+ { :var => "pubsub#publish_model", :value => "open" }]
19
+ })
20
+
21
+ # Set up XMPP options and start the Eventmachine, connect to XMPP server
22
+ #
23
+ def connect(username, password, server)
24
+ jid = "#{username}@#{server}"
25
+ client.setup(jid, password)
26
+ client.run
27
+ end
28
+
29
+ # Shut down XMPP connection
30
+ #
31
+ # @param [String] host Host represents the pubsub address, e.g. pubsub.norbit.npc.nicta.com.au
32
+ def disconnect(host)
33
+ shutdown
34
+ end
35
+
36
+ # Create a new pubsub node with additional configuration
37
+ #
38
+ # @param [String] node Pubsub node name
39
+ # @param [String] host Pubsub host address
40
+ def create_node(node, host, &block)
41
+ pubsub.create_with_configuration(node, PUBSUB_CONFIGURE, host, &callback_logging(__method__, node, &block))
42
+ end
43
+
44
+ # Delete a pubsub node
45
+ #
46
+ # @param [String] node Pubsub node name
47
+ # @param [String] host Pubsub host address
48
+ def delete_node(node, host, &block)
49
+ pubsub.delete(node, host, &callback_logging(__method__, node, &block))
50
+ end
51
+
52
+ # Subscribe to a pubsub node
53
+ #
54
+ # @param [String] node Pubsub node name
55
+ # @param [String] host Pubsub host address
56
+ def subscribe(node, host, &block)
57
+ pubsub.subscribe(node, nil, host, &callback_logging(__method__, node, &block))
58
+ end
59
+
60
+ # Un-subscribe all existing subscriptions from all pubsub nodes.
61
+ #
62
+ # @param [String] host Pubsub host address
63
+ def unsubscribe(host)
64
+ pubsub.subscriptions(host) do |m|
65
+ m[:subscribed] && m[:subscribed].each do |s|
66
+ pubsub.unsubscribe(s[:node], nil, s[:subid], host, &callback_logging(__method__, s[:node], s[:subid]))
67
+ end
68
+ end
69
+ end
70
+
71
+ # Publish to a pubsub node
72
+ #
73
+ # @param [String] node Pubsub node name
74
+ # @param [String] message Any XML fragment to be sent as payload
75
+ # @param [String] host Pubsub host address
76
+ def publish(node, message, host, &block)
77
+ pubsub.publish(node, message, host, &callback_logging(__method__, node, message.operation, &block))
78
+ end
79
+
80
+ # Event callback for pubsub node event(item published)
81
+ #
82
+ def node_event(*args, &block)
83
+ pubsub_event(:items?, *args, &callback_logging(__method__, &block))
84
+ end
85
+
86
+ private
87
+
88
+ # Provide a new block wrap to automatically log errors
89
+ def callback_logging(*args, &block)
90
+ m = args.empty? ? "OPERATION" : args.map {|v| v.to_s.upcase }.join(" ")
91
+ proc do |callback|
92
+ logger.error callback if callback.respond_to?(:error?) && callback.error?
93
+ logger.debug "#{m} SUCCEED" if callback.respond_to?(:result?) && callback.result?
94
+ block.call(callback) if block
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,118 @@
1
+ require 'niceogiri'
2
+ require 'hashie'
3
+ require 'securerandom'
4
+ require 'openssl'
5
+
6
+ module OmfCommon
7
+ # Refer to resource life cycle, instance methods are basically construct & parse XML fragment
8
+ #
9
+ # @example To create a valid omf message, e.g. a 'configure' message:
10
+ #
11
+ # Message.request do |message|
12
+ # message.property('os', 'debian')
13
+ # message.property('memory', 2) do |p|
14
+ # p.element('unit', 'gb')
15
+ # end
16
+ # end.sign
17
+ #
18
+ class Message < Niceogiri::XML::Node
19
+ OMF_NAMESPACE = "http://schema.mytestbed.net/#{OmfCommon::PROTOCOL_VERSION}/protocol"
20
+ SCHEMA_FILE = "#{File.dirname(__FILE__)}/protocol.rng"
21
+ OPERATION = %w(create configure request release inform)
22
+
23
+ class << self
24
+ OPERATION.each do |operation|
25
+ define_method(operation) do |*args, &block|
26
+ xml = new(operation, nil, OMF_NAMESPACE)
27
+ xml.element('context_id', operation == 'inform' ? args[0] : SecureRandom.uuid)
28
+ xml.element('publish_to', args[0]) if operation == 'request'
29
+ xml.element('inform_type', args[1]) if operation == 'inform'
30
+ block.call(xml) if block
31
+ xml
32
+ end
33
+ end
34
+
35
+ def parse(xml)
36
+ xml_root = Nokogiri::XML(xml).root
37
+ new(xml_root.element_name, nil, xml_root.namespace.href).inherit(xml_root)
38
+ end
39
+ end
40
+
41
+ def property(key, value = nil, &block)
42
+ key_node = Message.new('property')
43
+ key_node.write_attr('key', key)
44
+ add_child(key_node)
45
+ if block
46
+ key_node.element('value', value) if value
47
+ block.call(key_node)
48
+ else
49
+ key_node.content = value if value
50
+ end
51
+ key_node
52
+ end
53
+
54
+ # Generate SHA1 of canonicalised xml and write into the ID attribute of the message
55
+ #
56
+ def sign
57
+ write_attr('msg_id', OpenSSL::Digest::SHA1.new(canonicalize)) if read_attr('id').nil? || read_attr('id').empty?
58
+ self
59
+ end
60
+
61
+ def valid?
62
+ validation = Nokogiri::XML::RelaxNG(File.open(SCHEMA_FILE)).validate(document)
63
+ if validation.empty?
64
+ true
65
+ else
66
+ logger.error validation.map(&:message).join("\n")
67
+ false
68
+ end
69
+ end
70
+
71
+ def element(key, value)
72
+ key_node = Niceogiri::XML::Node.new(key)
73
+ key_node.content = value
74
+ add_child(key_node)
75
+ end
76
+
77
+ # The root element_name represents operation
78
+ #
79
+ def operation
80
+ element_name.to_sym
81
+ end
82
+
83
+ def element_by_xpath_with_default_namespace(xpath_without_ns)
84
+ xpath(xpath_without_ns.gsub(/(\/+)(\w+)/, '\1xmlns:\2'), :xmlns => OMF_NAMESPACE)
85
+ end
86
+
87
+ # In case you think method :element_by_xpath_with_default_namespace is too long
88
+ #
89
+ alias_method :read_element, :element_by_xpath_with_default_namespace
90
+
91
+ # We just want to know the content of an non-repeatable element
92
+ #
93
+ def read_content(element_name)
94
+ read_element("//#{element_name}").first.content rescue nil
95
+ end
96
+
97
+ # Get a property by key
98
+ #
99
+ # @param [String] key name of the property element
100
+ # @return [Object] the content of the property, as string, integer, float, or mash(hash with indifferent access)
101
+ #
102
+ def read_property(key)
103
+ key = key.to_s
104
+ e = read_element("//property[@key='#{key}']").first
105
+ if e
106
+ if e.children.size == 1
107
+ e.content.ducktype
108
+ else
109
+ Hashie::Mash.new.tap do |mash|
110
+ e.element_children.each do |child|
111
+ mash[child.element_name] ||= child.content.ducktype
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,42 @@
1
+ default namespace = "http://schema.mytestbed.net/6.0/protocol"
2
+
3
+ element (create | configure) {
4
+ attribute msg_id { text },
5
+ element context_id { text },
6
+ element property {
7
+ (attribute key { text } | element key { text }),
8
+ (attribute type { text } | element type { text })?,
9
+ (element value { text } | text),
10
+ element unit { text }?,
11
+ element precision { text }?
12
+ }*
13
+ } |
14
+ element request {
15
+ attribute msg_id { text },
16
+ element context_id { text },
17
+ element publish_to { text }?,
18
+ element property {
19
+ (attribute key { text } | element key { text }),
20
+ element min_value { text }?,
21
+ element max_value { text }?
22
+ }*
23
+ } |
24
+ element inform {
25
+ attribute msg_id { text },
26
+ element context_id { text },
27
+ element inform_type { "CREATED" | "FAILED" | "STATUS" | "RELEASED" },
28
+ element resource_id { text }?,
29
+ element resource_address { text }?,
30
+ element error_message { text }?,
31
+ element property {
32
+ (attribute key { text } | element key { text }),
33
+ element current { text },
34
+ element target { text }?,
35
+ element msg { text }?,
36
+ element progress { text }?
37
+ }*
38
+ } |
39
+ element release {
40
+ attribute msg_id { text },
41
+ element context_id { text }
42
+ }
@@ -0,0 +1,141 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <choice ns="http://schema.mytestbed.net/6.0/protocol" xmlns="http://relaxng.org/ns/structure/1.0">
3
+ <element>
4
+ <choice>
5
+ <name>create</name>
6
+ <name>configure</name>
7
+ </choice>
8
+ <attribute name="msg_id"/>
9
+ <element name="context_id">
10
+ <text/>
11
+ </element>
12
+ <zeroOrMore>
13
+ <element name="property">
14
+ <choice>
15
+ <attribute name="key"/>
16
+ <element name="key">
17
+ <text/>
18
+ </element>
19
+ </choice>
20
+ <optional>
21
+ <choice>
22
+ <attribute name="type"/>
23
+ <element name="type">
24
+ <text/>
25
+ </element>
26
+ </choice>
27
+ </optional>
28
+ <choice>
29
+ <element name="value">
30
+ <text/>
31
+ </element>
32
+ <text/>
33
+ </choice>
34
+ <optional>
35
+ <element name="unit">
36
+ <text/>
37
+ </element>
38
+ </optional>
39
+ <optional>
40
+ <element name="precision">
41
+ <text/>
42
+ </element>
43
+ </optional>
44
+ </element>
45
+ </zeroOrMore>
46
+ </element>
47
+ <element name="request">
48
+ <attribute name="msg_id"/>
49
+ <element name="context_id">
50
+ <text/>
51
+ </element>
52
+ <optional>
53
+ <element name="publish_to">
54
+ <text/>
55
+ </element>
56
+ </optional>
57
+ <zeroOrMore>
58
+ <element name="property">
59
+ <choice>
60
+ <attribute name="key"/>
61
+ <element name="key">
62
+ <text/>
63
+ </element>
64
+ </choice>
65
+ <optional>
66
+ <element name="min_value">
67
+ <text/>
68
+ </element>
69
+ </optional>
70
+ <optional>
71
+ <element name="max_value">
72
+ <text/>
73
+ </element>
74
+ </optional>
75
+ </element>
76
+ </zeroOrMore>
77
+ </element>
78
+ <element name="inform">
79
+ <attribute name="msg_id"/>
80
+ <element name="context_id">
81
+ <text/>
82
+ </element>
83
+ <element name="inform_type">
84
+ <choice>
85
+ <value>CREATED</value>
86
+ <value>FAILED</value>
87
+ <value>STATUS</value>
88
+ <value>RELEASED</value>
89
+ </choice>
90
+ </element>
91
+ <optional>
92
+ <element name="resource_id">
93
+ <text/>
94
+ </element>
95
+ </optional>
96
+ <optional>
97
+ <element name="resource_address">
98
+ <text/>
99
+ </element>
100
+ </optional>
101
+ <optional>
102
+ <element name="error_message">
103
+ <text/>
104
+ </element>
105
+ </optional>
106
+ <zeroOrMore>
107
+ <element name="property">
108
+ <choice>
109
+ <attribute name="key"/>
110
+ <element name="key">
111
+ <text/>
112
+ </element>
113
+ </choice>
114
+ <element name="current">
115
+ <text/>
116
+ </element>
117
+ <optional>
118
+ <element name="target">
119
+ <text/>
120
+ </element>
121
+ </optional>
122
+ <optional>
123
+ <element name="msg">
124
+ <text/>
125
+ </element>
126
+ </optional>
127
+ <optional>
128
+ <element name="progress">
129
+ <text/>
130
+ </element>
131
+ </optional>
132
+ </element>
133
+ </zeroOrMore>
134
+ </element>
135
+ <element name="release">
136
+ <attribute name="msg_id"/>
137
+ <element name="context_id">
138
+ <text/>
139
+ </element>
140
+ </element>
141
+ </choice>
@@ -0,0 +1,4 @@
1
+ module OmfCommon
2
+ VERSION = "6.0.0.pre.1"
3
+ PROTOCOL_VERSION = "6.0"
4
+ end
data/lib/omf_common.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'logging'
2
+
3
+ require "omf_common/version"
4
+ require "omf_common/message"
5
+ require "omf_common/comm"
6
+ require "omf_common/command"
7
+ require "omf_common/core_ext/string"
8
+
9
+ include Logging.globally
10
+
11
+ Logging.appenders.stdout('stdout',
12
+ :layout => Logging.layouts.pattern(:date_pattern => '%F %T %z',
13
+ :pattern => '[%d] %-5l %m\n',
14
+ :color_scheme => 'default'))
15
+ Logging.logger.root.appenders = 'stdout'
16
+ Logging.logger.root.level = :info
17
+
18
+ module OmfCommon
19
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "omf_common/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "omf_common"
7
+ s.version = OmfCommon::VERSION
8
+ s.authors = ["NICTA"]
9
+ s.email = ["omf-user@lists.nicta.com.au"]
10
+ s.homepage = "https://www.mytestbed.net"
11
+ s.summary = %q{Common library of OMF}
12
+ s.description = %q{Common library of OMF, a generic framework for controlling and managing networking testbeds.}
13
+
14
+ s.rubyforge_project = "omf_common"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "minitest", "~> 2.11.3"
23
+ s.add_runtime_dependency "blather", "~> 0.7"
24
+ s.add_runtime_dependency "logging", "~> 1.7.1"
25
+ s.add_runtime_dependency "hashie", "~> 1.2.0"
26
+ end
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ describe OmfCommon::Comm do
4
+ describe 'when initialised with a pubsub implementation' do
5
+ it 'must return a instance with all methods defined in corresponding module loaded' do
6
+ @comm = OmfCommon::Comm.new(:xmpp_blather)
7
+ %w(connect disconnect create_node delete_node subscribe unsubscribe publish).each do |m|
8
+ @comm.must_respond_to m
9
+ end
10
+
11
+ # also existing blather DSL should work too
12
+ %w(when_ready shutdown).each do |m|
13
+ @comm.must_respond_to m
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+ require 'omf_common/command'
3
+
4
+ describe OmfCommon::Command do
5
+ describe "when use util file to execute a system command" do
6
+ it "must not print anything to stdout if executed successfully" do
7
+ OmfCommon::Command.execute("date").must_match /^.+/
8
+ end
9
+
10
+ it "must capture and log errors if command not found" do
11
+ OmfCommon::Command.execute("dte -z").must_be_nil
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ describe String do
4
+ describe "when given a string" do
5
+ it "must response to to_n, camelcase, constant" do
6
+ "100.0".ducktype.must_equal 100.0
7
+ "i_am_a_string".ducktype.must_equal "i_am_a_string"
8
+ "i_am_a_string".camelcase.must_equal "IAmAString"
9
+ module IAmAString; end
10
+ "i_am_a_string".camelcase.constant.must_equal IAmAString
11
+ module IAmAString::Test; end
12
+ "IAmAString::Test".constant.must_equal IAmAString::Test
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,85 @@
1
+ require 'test_helper'
2
+
3
+ include OmfCommon
4
+
5
+ PROP_ELEMENTS = %w(p1 p2 p3)
6
+
7
+ describe OmfCommon::Message do
8
+ describe "when constructing valid messages" do
9
+ it "must return a create or configure XML element without failing" do
10
+ %w(create configure).each do |msg_name|
11
+ message = Message.send(msg_name) do |m|
12
+ PROP_ELEMENTS.each_with_index do |prop_element, index|
13
+ if index == 0
14
+ m.property(prop_element, rand(100))
15
+ else
16
+ m.property(prop_element, rand(100)) do |p|
17
+ p.element('unit', 'test')
18
+ p.element('precision', 'test')
19
+ end
20
+ end
21
+ end
22
+ end.sign
23
+ message.valid?.must_equal true
24
+ end
25
+ end
26
+
27
+ it "must return a request XML element without failing" do
28
+ request = Message.request('foo@bar') do |m|
29
+ PROP_ELEMENTS.each do |prop_element|
30
+ m.property(prop_element) do |p|
31
+ p.element('min_value', 'test')
32
+ p.element('max_value', 'test')
33
+ end
34
+ end
35
+ end.sign
36
+ request.valid?.must_equal true
37
+ end
38
+
39
+ it "must return a release XML element without failing" do
40
+ release = Message.release.sign
41
+ release.valid?.must_equal true
42
+ end
43
+
44
+ it "must return a inform XML element without failing" do
45
+ inform = Message.inform('9012c3bc-68de-459a-ac9f-530cc7168e22', 'CREATED') do |m|
46
+ m.element('resource_id', 'test')
47
+ m.element('resource_address', 'test')
48
+ PROP_ELEMENTS.each do |prop_element|
49
+ m.property(prop_element) do |p|
50
+ p.element('current', 'test')
51
+ p.element('target', 'test')
52
+ end
53
+ end
54
+ end.sign
55
+ inform.valid?.must_equal true
56
+ end
57
+ end
58
+
59
+ describe "must be able to parse a XML element into Message object" do
60
+ it "must behave" do
61
+ xml = Message.create do |m|
62
+ m.property('type', 'vm')
63
+ m.property('os', 'debian')
64
+ m.property('memory', 1024) do |p|
65
+ p.element('unit', 'mb')
66
+ p.element('precision', '0')
67
+ end
68
+ end.sign.to_xml
69
+
70
+ message = Message.parse(xml)
71
+
72
+ message.must_be_kind_of Message
73
+ message.operation.must_equal :create
74
+ message.read_element("//property").size.must_equal 3
75
+ message.read_content("unit").must_equal 'mb'
76
+ message.read_element("/create/property").size.must_equal 3
77
+ message.read_property("type").must_equal 'vm'
78
+ message.read_property(:type).must_equal 'vm'
79
+ memory = message.read_property(:memory)
80
+ memory.value.must_equal 1024
81
+ memory.unit.must_equal 'mb'
82
+ memory.precision.must_equal 0
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,9 @@
1
+ gem 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'minitest/pride'
4
+
5
+ require 'omf_common'
6
+
7
+ # Shut up all the loggers
8
+ Logging.logger.root.clear_appenders
9
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omf_common
3
+ version: !ruby/object:Gem::Version
4
+ version: 6.0.0.pre.1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - NICTA
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.11.3
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.11.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: blather
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '0.7'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '0.7'
46
+ - !ruby/object:Gem::Dependency
47
+ name: logging
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.7.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.7.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: hashie
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.2.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.2.0
78
+ description: Common library of OMF, a generic framework for controlling and managing
79
+ networking testbeds.
80
+ email:
81
+ - omf-user@lists.nicta.com.au
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - Gemfile
88
+ - Rakefile
89
+ - lib/omf_common.rb
90
+ - lib/omf_common/comm.rb
91
+ - lib/omf_common/command.rb
92
+ - lib/omf_common/core_ext/blather/dsl.rb
93
+ - lib/omf_common/core_ext/blather/dsl/pubsub.rb
94
+ - lib/omf_common/core_ext/blather/stanza/registration.rb
95
+ - lib/omf_common/core_ext/string.rb
96
+ - lib/omf_common/dsl/xmpp_blather.rb
97
+ - lib/omf_common/message.rb
98
+ - lib/omf_common/protocol.rnc
99
+ - lib/omf_common/protocol.rng
100
+ - lib/omf_common/version.rb
101
+ - omf_common.gemspec
102
+ - test/omf_common/comm_spec.rb
103
+ - test/omf_common/command_spec.rb
104
+ - test/omf_common/core_ext/string_spec.rb
105
+ - test/omf_common/message_spec.rb
106
+ - test/test_helper.rb
107
+ homepage: https://www.mytestbed.net
108
+ licenses: []
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ! '>'
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.1
125
+ requirements: []
126
+ rubyforge_project: omf_common
127
+ rubygems_version: 1.8.23
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: Common library of OMF
131
+ test_files: []
132
+ has_rdoc: